diff --git a/.changelog/Release_0-72-0.md b/.changelog/Release_0-72-0.md new file mode 100644 index 0000000000..4c06223aa5 --- /dev/null +++ b/.changelog/Release_0-72-0.md @@ -0,0 +1,110 @@ +# Release Changelog + + +## [0.72.0] - 2022-12-25 - Replay Update & MSD Changes + +### Added +- Chart Author added to Rebirth and Til Death gameplay splash intro - [b577648](../../../commit/b57764807c03a61ef83be8fdb1f2f97ff2f63a7a) [c1fc66c](../../../commit/c1fc66c416b41a00f9c65248fcd9eb4dac5646cb) [10ed579](../../../commit/10ed579efbabf25f7ae12880d9772ec8c8de86a1) +- ClearTypes added to Rebirth Help - [db47b01](../../../commit/db47b01cda85c12a027faff8242a3d0da6b65846) +- Custom Window Config System in Rebirth and Til Death - [56a5a71](../../../commit/56a5a7144a1fa135f5247d818738ba1cd9e4801e) [82529f3](../../../commit/82529f34d5cb51bc93335439aceff02089229faf) [a7e8c62](../../../commit/a7e8c621bf3a69b80d9b1f0fb504e56a7c023205) [a96705b](../../../commit/a96705bd34e7a6b9c601ae71c9c0b93d38a33fa2) [3f4b934](../../../commit/3f4b93437ae10e2b0f9eec20f82149fc4e6b2275) [fded0b3](../../../commit/fded0b392b60060c31f927baad27bfcc1226c9a4) [9a01025](../../../commit/9a0102578796e6dec170092ec95a38fdd9e53c4f) [141b63a](../../../commit/141b63a7445d92b4a69ce3636085469e5cc0b27f) [569eec9](../../../commit/569eec910480b5e820f071f55c40c1dab0baf4e2) [2f3800d](../../../commit/2f3800dd7f8264601336fb7e8ee7ab09ff5ec9fc) [dbb0ab4](../../../commit/dbb0ab490a62faf7ddccba2a89fc6fa2fd67c5c2) [3ffeb53](../../../commit/3ffeb539cd3ea7acc808a6bfab7b0f9b87c2c65d) [0f68e3d](../../../commit/0f68e3d1b0dc0149a718aec51ab5f9cf6e8266b9) [f012002](../../../commit/f01200230cfcbc4ffe71278544e25a0c50787aed) [88b7860](../../../commit/88b78603cc020f05fb37fb67d609d879c4c3782a) [abff9d1](../../../commit/abff9d105a45cd0abedaa22284a23d206724d49d) [298c406](../../../commit/298c4063d260c022218e8d3cef7ab0089663c26d) [09b3f23](../../../commit/09b3f23868946a28079b59103b2420a27907698b) [6546a74](../../../commit/6546a74601ff4e7b465f4a3e6468cc578a5658cc) [f0a5a26](../../../commit/f0a5a26815f25200a4ef17a2f599f4a14c5cbe46) [3d1dda6](../../../commit/3d1dda648b38d92b3774f323079069e97379d85b) [4fd80d5](../../../commit/4fd80d5a27bf7f337f0531bc8fc10d058d3c0c47) [54a341d](../../../commit/54a341db6b9143e531de528deb2bedae3d5ebdb2) +- Global Offset can be adjusted directly in legacy Graphics Options - [87b26c2](../../../commit/87b26c2e4bb9729555f7c8f9e82abe0ed8f38395) +- H-ran Shuffle mod, a variant of SuperShuffle which specifically avoids making jacks - [540a298](../../../commit/540a29837402e0a840bd81ee87c2f6ba7290d687) +- Hovering CDTitle in Til Death shows Chart Author if available - [c3e0ccf](../../../commit/c3e0ccfcfc5f9a47aeecfa7834b4aeb7cdc6e5c5) +- Internal method for getting Style from StepsType for Steps - [c1e68b6](../../../commit/c1e68b6082f3df3838fff56c39f154286499e00c) +- Internal method NOTESKIN->GetMetric has a defaulting variant - [b7fa469](../../../commit/b7fa469f896eaacefdb078e84c684356bfb58197) +- Legacy PlayerOptions (the double enter menu) has an option for Clap/Metronome at the bottom of the Main page - [c37a5d7](../../../commit/c37a5d7700f62ab98d46de53da2abf35ca4377da) +- Lua bindings for getting Replays, ReplaySnapshots, related information - [5bfb0d9](../../../commit/5bfb0d908d5995ab67f7f81393b4c636f6b9cc03) [3e6fe84](../../../commit/3e6fe84ba95a569716ff661e7d0987d6bb11597d) [3c55e4c](../../../commit/3c55e4c963686b346595dbae7fdb574bcb973f8f) [e9846b7](../../../commit/e9846b703aa92f7962566c8ed18328ae7c227fad) [ab32cd9](../../../commit/ab32cd97cbf9613dd036aa4fc7d705f521444ad4) +- Preference UnfocusedSleepMilliseconds to control the CPU usage of the game while tabbed out - [5f2c627](../../../commit/5f2c6278a5824a60af9f8ca03e468acf745e9e4a) +- Preference DebugMenuButtonToggles to allow pressing F3 instead of holding F3 to use debug menu - [1ff8714](../../../commit/1ff87144b04c8b9cd499a8c97a9a5ca65589a40e) +- Rebirth chart leaderboards show that scores are ChordCohesion On - [6dacfee](../../../commit/6dacfeed9cfbe32dca0e29c491391ce4bc86f9d2) +- Rebirth combo animations option - [626cc92](../../../commit/626cc92a789bef71dabd3d6d36e35fc3fc74da78) +- Rebirth gameplay leaderboard has a new option to show local scores only - [17d91f0](../../../commit/17d91f062f2bafb650c7d29d02bb1d4dd163b937) +- Rebirth has a progress bar for score uploads - [90ab3e3](../../../commit/90ab3e3b45d2fd9bae662366ee51268ad1b9bc4e) [42c65a3](../../../commit/42c65a361e97845cc6b3c916583b5061a354dc22) +- Rebirth has a new EWMA numerical display, and StdDev numerical display for gameplay - [a0432c9](../../../commit/a0432c9abee51420cdd072cd2dcc531655777eeb) +- Rebirth properly updates goal information when pressing Ctrl+G - [5b7bc63](../../../commit/5b7bc636b23524de5039a8878d9180223566f323) +- RNG seed is tracked for new replays and scores to allow shuffle plays to be recreated - [7c375b8](../../../commit/7c375b88a504ecc9035ea9a13842199f72cde65f) [dbb3444](../../../commit/dbb3444df9312c50e74b4b550c385ea53bbf241f) [0db1b2b](../../../commit/0db1b2b95f8fc497b788dcd723c142fd42389600) [f562787](../../../commit/f5627873724795a221db3ce7655865e8647440cc) +- ScreenTextEntry can be closed correctly from Lua - [4f97888](../../../commit/4f97888bdbb80b0138a5ba01c779d940d3e1024c) +- Successful logins are recorded in the log - [ed034d7](../../../commit/ed034d737f8e40d43b78f16caac31929965bed15) +- Theme option ShowBanners added to Til Death and Rebirth - [52884a8](../../../commit/52884a8aa63c1e52c3c8d9c98eeff8bbc183f6f6) [23cf20e](../../../commit/23cf20e0799c6a3fc5f7b363b3d173632c030e75) +- Translation to Japanese (work in progress) added for Til Death - [296ff53](../../../commit/296ff53edb837121f2ec9b112507d9fd906820d7) [6038d77](../../../commit/6038d7702d8fd5e8dafd2ad999187d153439454a) +- Translation support added to Rebirth, with partial Japanese translation - [c3984aa](../../../commit/c3984aae6bb8c8266e1cf436a6648de401ce8949) [f2cb239](../../../commit/f2cb2391facd7a02048e29e15af0b04fdf206ea2) [492e038](../../../commit/492e0380f3c62c4135030a3aeace24b6061bcf6d) [358c626](../../../commit/358c626fce8b3a155faf7498460798fa2ac2a916) +- Translation support for crashpad upload opt in dialogue - [4879d05](../../../commit/4879d0545f5c96a04d3756067f797df01dd2d26f) + +### Changed +- Arbitrary lower bound to gameplay position (-2000) changed to -200000 - [f0ec65c](../../../commit/f0ec65cc4dfcec60cc0797c6d737cabb3b2e042c) +- C++ standard moved to C++20 - [#1071](../../../pull/1071) +- D3D renderer error reporting improved - [6825be3](../../../commit/6825be35183c67e3b816ee7182bd7b3567c4af9c) +- Difficulty Calculator (4k) has beeen updated from version 473 to 505 - [0ed44ae](../../../commit/0ed44ae4e1fc0d0627e002225d4cdcd06244e871) [eb97233](../../../commit/eb972332b59d57aa3f01249e5c7f231b0f6320e4) [a625a1e](../../../commit/a625a1e9ef28de5fb8616c5947db2c29fa095eff) [b0707ff](../../../commit/b0707ffb409a8be90339811c022445a8b184c92f) [3dd76cf](../../../commit/3dd76cf20f0fb1d4dbe72b50ae79fff80f5153bc) [ca2ae1d](../../../commit/ca2ae1d1c16bd580a8f3b763ac8f05a1e625196d) [26537b5](../../../commit/26537b5ea644be6e79f34c3571998174a1906f16) [9ff71c6](../../../commit/9ff71c64ea0805d841d8b1b2f91a831d4b542857) [c875c16](../../../commit/c875c16479518cb3b8b3eb5e55d2e5104eb173a1) [259a97a](../../../commit/259a97a15e8cbd8c04faa033223a3dd66743ebc6) [ab74368](../../../commit/ab743680ed299471f457e489276cf19e1a944df2) [81bff01](../../../commit/81bff01835d2bbfeae8eb6f54f194879c1b88a56) [d0c1864](../../../commit/d0c1864cbd8c03d83dbc53fe7966e8eebe9fb9ce) [fe4aae0](../../../commit/fe4aae09ac8384598c7fd4ebedf48e7d320303c3) [e413cea](../../../commit/e413cea42529191cd100b95d09b0707fb0115248) [3386b83](../../../commit/3386b83e4693db85d466b081e54995e5c085accc) [737f612](../../../commit/737f612b1b39886bae3b25f995889e909ec7edf0) [85d02e1](../../../commit/85d02e1e5a2f6819103f8560cd3337bd5795f576) [f9b9b4f](../../../commit/f9b9b4fb7a8187ffbfbcc553974153fa5e58109e) [d7593e0](../../../commit/d7593e0f6a6962c964d10231576f7651d805108f) [2ab44f2](../../../commit/2ab44f20825e623195d78e587320d20ce448ede3) [90c23cd](../../../commit/90c23cd595a362e45c973e7cb61c634f97334616) [49bf467](../../../commit/49bf467763ce08bf057ae5cd1acc1199d362e124) [fbab3ec](../../../commit/fbab3ec210f73429e8a05c225055431564683a31) [86d8a34](../../../commit/86d8a343f7733fb2b0ea9b277fbecce6082795fa) [d87bd36](../../../commit/d87bd36069b93aa64ce7239fa938ad97ea2a6ccf) [ba33d50](../../../commit/ba33d506b79de76187ff52ca239f72fd6457595a) [877d46a](../../../commit/877d46ae88f9d7d6c887a7e954192bd757399cc1) [#1202](../../../pull/1202) [adca9c6](../../../commit/adca9c6ad93a5b9db8356c1d20280260f74c839a) [1173706](../../../commit/11737066fc6189dd030bf4395f694528a96c81a3) [282db31](../../../commit/282db3135c4ab79a0e1bf0f5cb757e0793954cf3) [3f1bb12](../../../commit/3f1bb12f5219bc42928ec5c37cfef1ba07692b8e) [433ac93](../../../commit/433ac93e2075f96a79de0a4b77a18dcf2aea146b) [330d279](../../../commit/330d2791d6495b41814c613472d5c003278aefbd) [884b50b](../../../commit/884b50bde67c0742b7bd576333d86f87199a2599) [722dcb2](../../../commit/722dcb2de9ee3861f4931b8dcaa6563d8d08ab1c) [b1c1482](../../../commit/b1c1482d4c82c8fbd2a20ea5251581c0a99fbd28) [6f51da8](../../../commit/6f51da843f9902fc034023b8235e55714863b2b5) [735668b](../../../commit/735668b24d0f708fcd50c914ae1cb4ae13fa7fce) +- Exploits by directly changing the internal timing window value to below J4 no longer possible - [ad59f11](../../../commit/ad59f1113f5883ff7cc3b2c0e7d92917398c81bc) +- Exploits by using Lua in Gameplay in some ways no longer possible - [e89d68c](../../../commit/e89d68ce83a0a686fa892e27c49f61355cdc7376) [176e2eb](../../../commit/176e2ebe5d20d70c8ccaf72d3ef36267cf097f31) +- Fallback ScreenProfileSave no longer says profiles are saving. Profiles don't save here - [d2af341](../../../commit/d2af341ca94aa5af7b49212123b916192982db5d) +- Fakes no longer take priority over other surrounding notes and eat inputs, like mines used to - [d6e374f](../../../commit/d6e374f7054f3fb7fae6e863ce4796ac67c9e121) +- Fake Notes globally defaulted to 25% opacity. Added NoteOpacityMultiplier to undo this change for your Noteskins - [e4def5f](../../../commit/e4def5fa4075f4d9138cf449fcb5c6f2cdc421cc) [38cf1c8](../../../commit/38cf1c8d403952540567364a9faa37ddcfef605b) +- Hardcoded 180ms limit made more obvious that it is a hardcoded constant - [76c1b7c](../../../commit/76c1b7ca4c6b4cfc6576f5f791b0795fe6ab56f9) +- Holds and Rolls can no longer have their life changed by directly modifying the timing window - [c24c61a](../../../commit/c24c61a31d20df2eacf6433d4c17858bcefb602c) +- Hovering CDTitle area in Rebirth always works even if the CDTitle is gone - [e962b85](../../../commit/e962b85ae68c0ebc6ecb03ca809b0ebd0289f15f) +- Invalid Modifiers message updated to be more clear that you are invalidating a score by using the mods - [8220a47](../../../commit/8220a476af45e16b18908f67e00f10482e5c7ae3) +- Log Output related to ALSA drivers - [3c6ffbf](../../../commit/3c6ffbff890f620c3e3d3785802c499cbaab314e) +- Log Output related to Score Uploads - [c0314d4](../../../commit/c0314d4ce24ac1098f2b911e5d470fb84a5c5b80) +- Mechanic to prevent early CBs for hitting an incoming note while inside an alive Hold/Roll has been forced to the J4 Good window - [7ceaa51](../../../commit/7ceaa518a6fcd8a3ba0ab171992a00892406619d) +- MSD for short files is unnerfed, but SSR remains the same - [bab294a](../../../commit/bab294a54e02da79d02ea8e3ba704478e1079b2d) +- Noteskins globally forced to load textures at max resolution to prevent spritesheet issues - [f768506](../../../commit/f768506a06c2a053e202ba76df476e7ec5bd926b) +- Pack Downloads no longer bound by FPS: DownloadManager moved to its own thread - [#1199](../../../pull/1199) [1fdd5bf](../../../commit/1fdd5bf6d0ba0241e63c17f1e5231c768eac42f2) [#1200](../../../pull/1200) [8967aed](../../../commit/8967aedb5ee06648dd092785d33fe548c75437c7) +- Rebirth chart preview was remade so that it isn't so bad. It's probably still a little bad - [1bbada1](../../../commit/1bbada18c5e3e5eba22c3bf339c9249a5e4f19ac) +- Rebirth evaluation banner should now always be 3.2 aspect ratio, same as SelectMusic - [a01a587](../../../commit/a01a58796c7ac5a74e59edb44696f3d0b122b6e1) +- Rebirth goal tracker 96.65% increment moved to 96.5% - [0476317](../../../commit/047631753073641bc6d0e38d586bbe6e02ea5dcd) +- Rebirth language changes force the theme to reload like a graphics change - [d3b600f](../../../commit/d3b600fc92fe4b9c5bcf22cc607e737ec89358a7) +- Renamed the fallback names for W1 and W5 to Marvelous and Bad from Flawless and Boo - [23244dd](../../../commit/23244dd4646d0dc2b36db150073ef8c7e792b888) +- Replays always save if the play is new and man-made - [97d0960](../../../commit/97d0960a0877a6376002fa7da59857af3f59c09d) +- Rewrote replay system to add support for processing replays and playing them back properly no matter the format given. - [c4bedf8](../../../commit/c4bedf833bfac46cc8934dd676c2a6767b43323a) [eee60bd](../../../commit/eee60bd7195e04dfe92a954ada4dc2d8c5399b2c) [a781a50](../../../commit/a781a509decc8f9653c09ca7f4f4280d6b988a8d) [55a4199](../../../commit/55a4199bf5be73638093db6136fac5215440e54e) [de5abcd](../../../commit/de5abcd22c4652f6cd442b5e86e602fcab94e18f) [343d09f](../../../commit/343d09f053f533a3df9a9e314c84e38103e5b857) [480b5fd](../../../commit/480b5fd9089494cf9ff6434c45bb24264794f23a) [1d8ee7f](../../../commit/1d8ee7f741a9a96eacb384eeaa6bd043044f7fd3) [7b4b1dd](../../../commit/7b4b1dd8eb504a0aeeeec4eaf5bd48f130577b0b) [08746de](../../../commit/08746dea47f1d6bad497639d2eef2f58446f858b) [f1c2eb2](../../../commit/f1c2eb23f9329a331a83d57ba80ae7ed16d12e1e) [97d0960](../../../commit/97d0960a0877a6376002fa7da59857af3f59c09d) [065745b](../../../commit/065745b1360ea82da7d1b25dcaec0f3ff5ac4c1b) [979e531](../../../commit/979e53147d7433ba7ef1ed4bb22d0e4ba3234b6d) [ea3e98f](../../../commit/ea3e98f0b126bc5e63c190c8ef5206ad003169e3) [7c375b8](../../../commit/7c375b88a504ecc9035ea9a13842199f72cde65f) [1e1877d](../../../commit/1e1877d1d65186dcd325e14620ae93adf90ccf78) [dd9ee61](../../../commit/dd9ee61acf857180c1d26d84ce2ad4794f8fa5cd) [f562787](../../../commit/f5627873724795a221db3ce7655865e8647440cc) [bf41374](../../../commit/bf41374ca60c14ae4d3220b2a27e0f3ce76806a1) [d92b6c7](../../../commit/d92b6c7fb2d2df35224ddb886a9cb5159988e299) [4b30d98](../../../commit/4b30d989c3e8d9aa2e52e2636b0c4304648ef44b) [97288f7](../../../commit/97288f78297c77684ac4aea6fa8ca976f6432a2c) [6b863f0](../../../commit/6b863f0e6a11e782914b2d07b1050049df742ebb) [2c0262f](../../../commit/2c0262fb8f9e3948b264af61cf33aa63e4efb705) [6d538c0](../../../commit/6d538c01bffe599d0d33f4b5d31c493835d401a8) [36ca5de](../../../commit/36ca5de2a83eac3176e0209a9e781e7d6e58af47) [fbf9f32](../../../commit/fbf9f32cc10f3f984e2be4e9a2d1c3c2c16cf111) [47d07db](../../../commit/47d07db6fe9fd516c0944c2f5b34ef2a5c6712ac) [61cc435](../../../commit/61cc435036c1bcb6d75acd1d5c09a229736a37c9) [8eaab46](../../../commit/8eaab46fee883c810f24db0a6a7bff7b4d3a553b) [2280135](../../../commit/2280135d92fd8fd44baa2a5998f997507b15915e) [8952c44](../../../commit/8952c4487df286bddc1ec44cfd8b08d65d0a4d28) +- Replay system can reprocess replays to change note priority - [6d538c0](../../../commit/6d538c01bffe599d0d33f4b5d31c493835d401a8) [754bbbe](../../../commit/754bbbe038ff4de3670c165bb83b759db4961a09) +- Replay system in gameplay will play back ghost taps for local replays recorded after this release - [480b5fd](../../../commit/480b5fd9089494cf9ff6434c45bb24264794f23a) [bf04f3e](../../../commit/bf04f3eb726e8703b69b4a37428c086b3da0e9e4) [86a70a0](../../../commit/86a70a011c15f510c5ced027ef44889f9c0b3215) [4be5c99](../../../commit/4be5c99b50eb78079fc9b9a6a24ce1c74cab41ae) [39e9093](../../../commit/39e909315cb870e4547665ffa1fe2a268cd1347a) [0785900](../../../commit/078590018781d142d912b4b9e1a3b8653e9def87) +- Scores over 100% and scores which have invalidating mods should be force invalidated - [18b4c3f](../../../commit/18b4c3f62b10baf199aa6f29d8f6df25309b00d6) +- Til Death musicwheel should no longer send you to the first alphabetical song in your library for an invalid search - [6c44340](../../../commit/6c443405964ffa4a46724f5f0086a21d25788054) [d061a14](../../../commit/d061a1467638e9630decea1e941edafe13af34e2) [86a2d6c](../../../commit/86a2d6c6955fe99dd6fc1b83e93bc7ccf82a36be) +- Til Death SelectMusic leftmost buttons (you know the ones) are more meshed into the UI - [71df567](../../../commit/71df567990f65c40a782a7580981a5300c31237a) +- Translation for fallback/core game in Japanese updated - [2f67e7f](../../../commit/2f67e7f8f37c9af626b31bc5c85c0c764cc39b1e) +- ShowBackgrounds moved to Preferences and properly respected in Til Death and Rebirth - [3297f86](../../../commit/3297f86a1931cc7ea4e754da696187f49023576e) +- Unused Actor tree print thing changed - [53f71dc](../../../commit/53f71dcef8ca537f16f34b6065772bf0174ac125) +- Updated libcurl to 7_83_1 - [f1dd6fe](../../../commit/f1dd6fecc8fdf41a59aa00bd3e7d5609b906d04c) [32c3826](../../../commit/32c382682a081c35f16aa7a1382af3451ed973bb) [d92363d](../../../commit/d92363dbcb3571d093a73f9b3027f82e39d2b702) + +### Removed +- AutoPtrCopyOnWrite replaced with std::shared_ptr - [10a0fa7](../../../commit/10a0fa7f98976f02dc114d957002e4480f89b86e) [3f4e235](../../../commit/3f4e235f0f1dee5157855615c46b999bed96a719) +- Dead Noteskins - [1183c6b](../../../commit/1183c6b9563d86cab125907ea2b5c19fd250e800) [ab0acb9](../../../commit/ab0acb9be7127c2151d2ff6b4aed5cbe3bde9105) +- DefaultScoreType - [51c5b5c](../../../commit/51c5b5c84bff6153f2717b41fe8c43cb771925c5) +- InitialHoldLife - [c24c61a](../../../commit/c24c61a31d20df2eacf6433d4c17858bcefb602c) +- mapconv - [1df9cc3](../../../commit/1df9cc3b9cdafc0227e2f09dc6755eb8875d0d36) +- PlayerAI - [5ce77e0](../../../commit/5ce77e005824fc26856439743bd19d7377353eda) +- TimingWindowAdd - [f311cce](../../../commit/f311cce0346492461ac2d5ad93395653ce0e1b57) +- Unused GetChartLeaderboard Lua Binding (different from GetChartLeaderBoard) - [f348fe5](../../../commit/f348fe52543f6686f33b0d21e5a15f9699e83aab) +- Unused Preferences (SoundVolumeAttract, EditRecordModeLeadIn, ShowInstructions, WideScreen16_10, WideScreen16_9) - [5312a72](../../../commit/5312a727da76c7414afc787fb59794051f19700a) +- Unused Til Death theme preferences - [d22ff40](../../../commit/d22ff40a7d63d16680430266616fa0d2ee46158a) +- Unused Translation strings (not all) - [4ed6156](../../../commit/4ed61569c16743e5f4b0c9e9e989498208cbf150) +- using std::* in SongCacheIndex - [bd16b06](../../../commit/bd16b06853ea402799f5482f8f64d6d2cf365883) + +### Fixed +- BPMDisplay not accounting for individual Steps having different BPMs - [#1217](../../../pull/1217) [f3b1919](../../../commit/f3b1919bb0f15f63799dba19bde4febaf4c06340) [c8329f1](../../../commit/c8329f13c7f3fe33448affdc08d8e163da595052) +- Building Debug target used to complain about std::clamp bounds - [b89afef](../../../commit/b89afef6dd02b0e68de7dd9ace984b9c9ab875ed) +- Calculator issues with comparing float values - [#1202](../../../pull/1202) +- Coverity defects - [e471c52](../../../commit/e471c527803f3636f79244f1af4cb191703d2c1a) [bea0edc](../../../commit/bea0edc3f0cb4d683242f4eca0183247a7a5a697) [130ff33](../../../commit/130ff33523248d964d8e4f8afb1e4b54d19e2aef) [c03f194](../../../commit/c03f194be26ef9c400566c212ace163150778fbf) [7bdd1db](../../../commit/7bdd1db2e5a30acf4c7b134030495883034797ad) [7b94b75](../../../commit/7b94b754263dead3404852f7ec075a8636813888) [1b2282b](../../../commit/1b2282b0fbed5d9954a712f9a4f75de4d6555439) [0dfe383](../../../commit/0dfe383d3f5a95049ea1f5bd3ab42e99bb2a5fe4) [fa800c1](../../../commit/fa800c1715b332748a50074bd75824f84a17e9c1) [41e0ac7](../../../commit/41e0ac7430828cbca173cc80b18783f6caf721d4) [da9528a](../../../commit/da9528a3ccb1c71240df89f0a91cd0cd662b1c65) [1b75b4b](../../../commit/1b75b4b0bf7b00f02a6543ff1ec88203e8971a68) [933b1f7](../../../commit/933b1f7aff490cf048a5cd2b5966153795433e34) [8d34d3d](../../../commit/8d34d3d1d3336bd6f850dc37aec22454d5d70915) [e688a36](../../../commit/e688a36bab7b5ee1aa726092d3c4d05e5c6a702b) [053a857](../../../commit/053a8576c61b825e86bc57857d82bddbd9b154ec) [d6c2048](../../../commit/d6c2048938d7d34ad212954cbffcef2b5059c90a) [6b7843e](../../../commit/6b7843e8dc57799856b3f13fc59bc4e1fe3a34c3) [f9d747a](../../../commit/f9d747a6a71661591e8eda21453f62ad335c35af) [edd3f3c](../../../commit/edd3f3c47c1651079b9e452403ce200567ac3051) +- Crash due to downloading a file with an illegal filename - [8a93290](../../../commit/8a9329009edec1e6c7d14b507b741aff7457dd15) [1fdd5bf](../../../commit/1fdd5bf6d0ba0241e63c17f1e5231c768eac42f2) +- Crash due to memory leak while scrolling pack with many videos - [7dcf142](../../../commit/7dcf142091cbf360ebe8bf64a0e791a0e9a14696) +- Crash due to a missing theme metric - [d39c391](../../../commit/d39c391b803d00322d4e96db4e582bb78d47aaf8) +- Crash due to using ActorFrameTexture while on D3D and resetting the D3DDevice - [ffdac31](../../../commit/ffdac317cc6ecf2aa85f6b18f2ff18daee33a05e) +- Crash when applying song filter in such a way that it filters out the GameplaySyncMachine charts - [05d88c9](../../../commit/05d88c971d20c264d09e052fc6801a97b0c7c2c1) +- Deadlocks (some) related to audio playing - [6968a85](../../../commit/6968a853333ab07dde3d0f2b26a6168faf07629c) [a2b330f](../../../commit/a2b330f9734e33530ceac3a4f850f3bde99058ec) +- Errors due to loading a song with any BGChanges or BGVideos that was in the Ungrouped Songs category - [bfe659c](../../../commit/bfe659cdc8706f7527de19e26cca753fdebe0623) +- Invalid UTF8 in file paths are much more likely to load on Windows, but only for Windows 10+ users - [cb340f6](../../../commit/cb340f62b99edac7ee3cccc0719bd27fb30fb09a) +- Lua Error due to entering Rebirth Practice - [3261621](../../../commit/32616216304cd211fed701ba6f5305aa018d584a) +- Online HighScores never had the MissedHold field populated - [70956b5](../../../commit/70956b577bd826c74829098394572b4d8f4ecb51) +- Playlist creation caused an empty one to show sometimes, which couldn't be modified or deleted - [e464732](../../../commit/e464732c2af05cddd72cab65de8b64f7079e7426) +- Rebirth BGBrightness and ScreenFilter settings used to force either 0% or 100% - [f7fb44d](../../../commit/f7fb44d9353a88b01e3c830ae3aabfb4ca681eb9) +- Rebirth debug string used to pop up any time you change songs - [e02757e](../../../commit/e02757e2211c5b238fa2f3f3259e76d56dde0f78) +- Rebirth input breaking and causing crashes when using mouse to exit dialogues - [44ffda2](../../../commit/44ffda2009abb3e1e7c5af2393b7aaa7333827a2) +- Til Death gameplay leaderboard no longer causing broken gameplay for unranked charts - [5214e72](../../../commit/5214e727e8d711d98b467bb127e2365a0ee71cb2) +- Rarely used Rebirth WheelDataManager script error - [82c949d](../../../commit/82c949d72f1c3db284d8f7ec01e271249b9c6281) +- Rebirth Settings was missing an explanation string - [4038f31](../../../commit/4038f31e7017c4cc75e27b36e040fb8162a65f8b) +- Songs reloaded from disk would not fix chartkey pointers internally, so sometimes would not be searchable by chartkey - [044fc1b](../../../commit/044fc1baf6764dc7e98515f882327fff9988216d) +- Warnings caused by EnumTraits - [5fc253a](../../../commit/5fc253a2db29dc03b9f938b9ea8ed8fdf5e93672) +- Warnings relevant to clang - [96f3bbd](../../../commit/96f3bbd7200b43369c2a89c0b349d67ea91792fa) [cb58828](../../../commit/cb58828b8189fc71bbfff0a3b2b68ca6a88d9ab5) [1423ce2](../../../commit/1423ce21ba7af7a38c61350e9bdfa6f44cc76419) +- Warnings relevant to MSVC - [48b798d](../../../commit/48b798dcec0e2905f2459740be992c14db7d6ea2) [e964b0b](../../../commit/e964b0ba0573b75dc634b69662c545f00922df1d) +- XCode used to fail building because Macs - [9d478b8](../../../commit/9d478b805b214b196ec40ce57155e77085d95269) \ No newline at end of file diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index f5f7df4523..31e2545cc2 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -7,17 +7,19 @@ on: jobs: linux-x64: - name: Linux x64 (${{matrix.cfg.cpp-version}}) + name: Linux x64 (${{matrix.cfg.cxx}}) runs-on: ${{matrix.cfg.os}} strategy: fail-fast: false matrix: cfg: - - { os: ubuntu-18.04, cpp-version: g++-8, dist: false} - - { os: ubuntu-18.04, cpp-version: g++-9, dist: false} - - { os: ubuntu-18.04, cpp-version: clang++-7, dist: false} - - { os: ubuntu-18.04, cpp-version: clang++-8, dist: false} - - { os: ubuntu-18.04, cpp-version: clang++-9, dist: true} + - { os: ubuntu-20.04, apt: g++-8, cxx: g++-8, cc: gcc-8, dist: false} + - { os: ubuntu-20.04, apt: g++-9, cxx: g++-9, cc: gcc-9, dist: false} + - { os: ubuntu-20.04, apt: g++-10, cxx: g++-10, cc: gcc-10, dist: false} + - { os: ubuntu-20.04, apt: clang-9, cxx: clang++-9, cc: clang-9, dist: false} + - { os: ubuntu-20.04, apt: clang-10, cxx: clang++-10, cc: clang-10, dist: false} + - { os: ubuntu-20.04, apt: clang-11, cxx: clang++-11, cc: clang-11, dist: false} + - { os: ubuntu-20.04, apt: clang-12, cxx: clang++-12, cc: clang-12, dist: true} steps: - name: Checkout Etterna diff --git a/.github/workflows/coverity-scan.yml b/.github/workflows/coverity-scan.yml index 0dd2cbe24a..1978f0d049 100644 --- a/.github/workflows/coverity-scan.yml +++ b/.github/workflows/coverity-scan.yml @@ -17,7 +17,7 @@ jobs: path: main - name: Install apt dependencies - run: sudo apt update && sudo apt-get install ninja-build nasm libglew-dev libxrandr-dev libxtst-dev libpulse-dev libasound-dev libogg-dev libvorbis-dev + run: sudo apt update && sudo apt-get install ninja-build nasm libglew-dev libxrandr-dev libxtst-dev libpulse-dev libasound-dev libogg-dev libvorbis-dev libcurl4-openssl-dev - name: Download Coverity Build Tool run: | diff --git a/.gitignore b/.gitignore index ba9f2b275d..e1e1c7521b 100644 --- a/.gitignore +++ b/.gitignore @@ -69,14 +69,10 @@ !/NoteSkins/kb7/retrobar-razor_o2/ !/NoteSkins/pump/cmd/ -!/NoteSkins/pump/cmd-routine-p1/ -!/NoteSkins/pump/cmd-routine-p2/ !/NoteSkins/pump/complex/ !/NoteSkins/pump/default/ !/NoteSkins/pump/delta/ !/NoteSkins/pump/delta-note/ -!/NoteSkins/pump/delta-routine-p1/ -!/NoteSkins/pump/delta-routine-p2/ !/NoteSkins/pump/frame5p/ !/NoteSkins/pump/newextra/ !/NoteSkins/pump/pad/ diff --git a/CMake/Helpers/DocumentationTools.cmake b/CMake/Helpers/DocumentationTools.cmake index b817d48994..932b2c74fd 100644 --- a/CMake/Helpers/DocumentationTools.cmake +++ b/CMake/Helpers/DocumentationTools.cmake @@ -20,7 +20,7 @@ else() endif() # LDoc -find_program(LDOC_EXE "ldoc") +find_program(LDOC_EXE NAMES "ldoc" "ldoc.bat") if(NOT LDOC_EXE) message(STATUS "LDoc not found. Documentation target will not be created.") else() diff --git a/CMakeLists.txt b/CMakeLists.txt index bd2db30efd..d1ff15b01b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,12 +19,12 @@ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") # PROJECT WIDE SETUP project(Etterna - VERSION 0.71.2 + VERSION 0.72.0 HOMEPAGE_URL https://github.com/etternagame/etterna/ LANGUAGES C CXX ASM) ## CMake and Compiler Setup -set(CMAKE_CXX_STANDARD 17) # Minimum C++ Version +set(CMAKE_CXX_STANDARD 20) # Minimum C++ Version set(CMAKE_CXX_EXTENSIONS OFF) # True if compiler extensions are necessary. (Changes -std flag) set(CMAKE_CXX_STANDARD_REQUIRED ON) # True to require minimum C++ version to compile set(CMAKE_OSX_DEPLOYMENT_TARGET 10.10) # Tell xcodebuild to target an older osx platform diff --git a/Data/splash.png b/Data/splash.png index 21e8d8dc6f..4dfdfd3da9 100644 Binary files a/Data/splash.png and b/Data/splash.png differ diff --git a/Docs/Building.md b/Docs/Building.md index 1e2b527d85..a98116f77b 100644 --- a/Docs/Building.md +++ b/Docs/Building.md @@ -50,7 +50,7 @@ cmake -DOPENSSL_ROOT_DIR="/usr/local/opt/openssl" -G "Xcode" .. # macOS - Arch: `pacman -S openssl` - Alpine: `apk add openssl-dev` - macOS: `brew install openssl` - - Windows: A CMake compatible version of OpenSSL is available at [Shining Light Productions](https://slproweb.com/products/Win32OpenSSL.html) website. You will need the 32bit and 64bit installers if you plan on building both versions. It's reccomended to uninstall old versions to make sure CMake can find the correct latest version. Direct links: [32bit](https://slproweb.com/download/Win32OpenSSL-1_1_1i.exe), [64bit](https://slproweb.com/download/Win64OpenSSL-1_1_1i.exe) + - Windows: A CMake compatible version of OpenSSL is available at [Shining Light Productions](https://slproweb.com/products/Win32OpenSSL.html) website. You will need the 32bit and 64bit installers if you plan on building both versions. It's recommended to uninstall old versions to make sure CMake can find the correct latest version. Direct links: [32bit](https://slproweb.com/download/Win32OpenSSL-1_1_1s.exe), [64bit](https://slproweb.com/download/Win64OpenSSL-1_1_1s.exe). If these links are dead, look for the OpenSSL v1.1.1 install links (EXE or MSI) on the Shining Light Productions site. Typically we use the full versions rather than the Light versions. - [depot_tools](https://dev.chromium.org/developers/how-tos/install-depot-tools) - Installation is platform specific. To skip installing this, follow the relevant instructions in [CLI Project Generation](CLI-Project-Generation). ### Linux Dependencies @@ -139,7 +139,7 @@ We actively support the following CMake generators - macOS: `Ninja`, `Xcode`, `Unix Makefiles` - Linux: `Ninja`, `Unix Makefiles` -- Windows: `Ninja`, `Visual Studio 15 2017`, `Visual Studio 16 2019` _(Technically, with how the CMake script is setup, any generator as far back as_ `Visual Studio 9 2008` _should work), but it has only tested it with the above three._ +- Windows: `Ninja`, `Visual Studio 16 2019`, `Visual Studio 17 2022` For the `OPENSSL_ROOT_DIR` parameter, set the directory for where ever the openssl root directory is located. Here are possible options @@ -270,14 +270,14 @@ To run `cppcheck`, run the target. Running the target will be different dependin ### C++ Docs -Etterna uses [doxygen](http://www.doxygen.nl/) to build it's C++ documentation. Documentation is generated in a `doxygen` directory, inside the build directory. CMake is setup to make a target called `doxygen` if the executable found in the path. +Etterna uses [Doxygen](http://www.doxygen.nl/) to build it's C++ documentation. Documentation is generated in a `doxygen` directory, inside the build directory. CMake is setup to make a target called `doxygen` if the executable found in the path. - Debian: `apt install doxygen` - Fedora: `dnf install doxygen` - Arch: `pacman -S doxygen` - Alpine: `apk add doxygen` - macOS: `brew install doxygen` -- Windows: An installer is available at the [doxygen website](http://www.doxygen.nl/download.html). As with [cppcheck](#cppcheck), make sure the executable binary directory is added to your path. +- Windows: An installer is available at the [Doxygen website](http://www.doxygen.nl/download.html). As with [cppcheck](#cppcheck), make sure the executable binary directory is added to your path. Doxygen within CMake is able to use [graphviz](https://www.graphviz.org/download/) to generate better looking relationship/hierarchy graphs. You can see how to download it for your operating system at the [graphgiz download page](https://www.graphviz.org/download/). diff --git a/Docs/Contributing.md b/Docs/Contributing.md index 3d50976962..3730227a97 100644 --- a/Docs/Contributing.md +++ b/Docs/Contributing.md @@ -34,17 +34,21 @@ Currently, there's a lack of alternative themes (To the default one, Til Death) ## Documentation -The project is sorely lacking in documentation. The current aim is to document the Lua stuff in https://etternagame.github.io/Lua-For-Etterna/API/Lua.xml (This is forked from http://dguzek.github.io/Lua-For-SM5/API/Lua.xml, a community-made reference for SM5 Lua). We intend to get the C++ documentation done in https://etternagame.github.io/wiki/ (At first we wanted to make this page have 3 "sections": General, Lua and C++, but gave up). Then there is a general wiki with information that can be useful to end users (https://wiki.etternaonline.com/). +The project is sorely lacking in documentation. -## Translating +The current aim is to document the Lua stuff in https://etternagame.github.io/Lua-For-Etterna/API/Lua.xml (This is forked from https://quietly-turning.github.io/Lua-For-SM5/Luadoc/Lua.xml, a community-made reference for SM5 Lua). + +We intend to get the C++ documentation done in https://etternagame.github.io/wiki/ -The Til Death theme (Default) only has one translation available. In order to make others, simply copy etterna/Themes/Til Death/Languages/en.ini and translate all the right-side words (After the `=`). Also, a list of the words/text/captions/things that aren't translate-able in the theme would be useful to make them(Some of the text is hard-coded so it's not possible to translate it). +There is a general wiki with information that can be useful to end users (https://wiki.etternaonline.com/). + +## Translating A guide on this can be found in [the translations document](Translations.md). ## Packaging -A few people have complained about the lack of packages for Linux in general. If you'd like to, you can try working on a package for your favorite distro. I've already made a more-or-less functional debian package here: https://github.com/nico-abram/etterna/tree/debian/ +A few people have complained about the lack of packages for Linux in general. If you'd like to, you can try working on a package for your favorite distro. ## Graphic Design diff --git a/Docs/Translations.md b/Docs/Translations.md index eb6c0dbf3f..8b91e959ae 100644 --- a/Docs/Translations.md +++ b/Docs/Translations.md @@ -1,6 +1,6 @@ # Translations -Translation support has always been a part of Stepmania to some extent. With Etterna 0.67.0+ we have opened up the doors to translating most of Til Death and some more of the base game's strings. +Translation support has always been a part of Stepmania to some extent. With Etterna 0.67.0+ we have opened up the doors to translating most of Til Death, and Etterna 0.71.3+ adds support for translation of Rebirth, as well as some more of the base game's strings. * [Supported Languages](#Languages) * [The Process](#Process) @@ -22,7 +22,7 @@ Figuring out if your language is supported at the moment is mostly trial and err ## Process * Determine your 2 letter language combo from the lists found above. -* Locate `/Themes/_fallback/Languages/en.ini` and `/Themes/Til Death/Languages/en.ini` +* Locate `/Themes/_fallback/Languages/en.ini` and `/Themes/Til Death/Languages/en.ini` or `/Themes/Rebirth/Languages/en.ini` * Make a copy of both files and leave them in the same respective `Languages` folders. Rename the copies to use your 2 letter language combination. For example, Norwegian would be `no.ini` * Begin translating line by line in the new files. @@ -45,7 +45,7 @@ If you run into any lines to translate that you would like more context to in or Spawncamping-wallhack does not feature this full translation support, but could in the future. -For your own theme, these translations can be done the exact same way. The Language files accessible from your theme are only those in `_fallback/Languages` and `yourtheme/Languages`. This means that the Til Death strings are not available, but that does not stop you from taking them at your own leisure. +For your own theme, these translations can be done the exact same way. The Language files accessible from your theme are only those in `_fallback/Languages` and `yourtheme/Languages`. This means that the Til Death or Rebirth strings are not available, but that does not stop you from taking them at your own leisure. Adding additional strings to Til Death or any theme involves creating a new line in a designated section and then calling it with `THEME:GetString("section", "string name")`. We try to reduce calls to this by storing them in a table instead of loading them multiple times per Actor. This `GetString` function will look for the current language in the theme and fallback. Then it will look in the `en.ini` in the same order. If it finds nothing in all cases, then you get a missing string error. diff --git a/GameTools/mapconv/CMakeProject-mapconv.cmake b/GameTools/mapconv/CMakeProject-mapconv.cmake deleted file mode 100644 index a602eb214a..0000000000 --- a/GameTools/mapconv/CMakeProject-mapconv.cmake +++ /dev/null @@ -1,33 +0,0 @@ -if (NOT MSVC) - return() -endif() - -set(MAPCONV_DIR "${SM_SRC_DIR}/archutils/Win32") - -list(APPEND MAPCONV_SRC - "${MAPCONV_DIR}/mapconv.cpp" -) - -source_group("" FILES ${MAPCONV_SRC}) - -add_executable("mapconv" ${MAPCONV_SRC}) - -set_property(TARGET "mapconv" PROPERTY FOLDER "Internal Libraries") - -disable_project_warnings("mapconv") - -set_target_properties("mapconv" PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${SM_PROGRAM_DIR}" - RUNTIME_OUTPUT_DIRECTORY_RELEASE "${SM_PROGRAM_DIR}" - RUNTIME_OUTPUT_DIRECTORY_DEBUG "${SM_PROGRAM_DIR}" - RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${SM_PROGRAM_DIR}" - RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${SM_PROGRAM_DIR}" -) - -set_target_properties("mapconv" PROPERTIES - OUTPUT_NAME "mapconv" - RELEASE_OUTPUT_NAME "mapconv" - DEBUG_OUTPUT_NAME "mapconv" - MINSIZEREL_OUTPUT_NAME "mapconv" - RELWITHDEBINFO_OUTPUT_NAME "mapconv" -) \ No newline at end of file diff --git a/GameTools/mapconv/mapconv.cpp b/GameTools/mapconv/mapconv.cpp deleted file mode 100644 index d9d56cc77f..0000000000 --- a/GameTools/mapconv/mapconv.cpp +++ /dev/null @@ -1,348 +0,0 @@ -// mapconv - symbolic debugging info generator for VirtualDub - -#include -#include - -#include -#include -#include -#include - -#define MAX_FNAMBUF (0x0FFFFFFF) -#define MAX_SEGMENTS (64) -#define MAX_GROUPS (64) - -struct RVAEnt -{ - long rva; - char* line; -}; - -std::vector rvabuf; - -char fnambuf[MAX_FNAMBUF]; -char* fnamptr = fnambuf; - -long segbuf[MAX_SEGMENTS][2]; -int segcnt = 0; -int seggrp[MAX_SEGMENTS]; -long grpstart[MAX_GROUPS]; - -char line[8192]; -long codeseg_flags = 0; -FILE *f, *fo; - -char* -strtack(char* s, const char* t, const char* s_max) -{ - while (s < s_max && (*s = *t)) - ++s, ++t; - - if (s == s_max) - return nullptr; - - return s + 1; -} - -bool -readline() -{ - if (!fgets(line, sizeof line, f)) - return false; - - int l = strlen(line); - - if (l > 0 && line[l - 1] == '\n') - line[l - 1] = 0; - - return true; -} - -bool -findline(const char* searchstr) -{ - while (readline()) { - if (strstr(line, searchstr)) - return true; - } - - return false; -} - -/////////////////////////////////////////////////////////////////////////// - -/* dbghelp UnDecorateSymbolName() doesn't handle anonymous namespaces, - * which look like "?A0x30dd143a". Remove "@?A0x????????"; we don't - * want to see "::" in crash dump output, anyway. */ -void -RemoveAnonymousNamespaces(char* p) -{ - while (p = strstr(p, "@?A")) { - int skip = 0, i; - if (strlen(p) < 13) - break; - - for (i = 5; i < 13; ++i) - if (!isxdigit(p[i])) - skip = 1; - if (p[3] != '0' || p[4] != 'x') - skip = 1; - if (skip) { - ++p; - continue; - } - - memmove(p, p + 13, strlen(p + 13) + 1); - } -} - -void -parsename(long rva, char* func_name) -{ - RemoveAnonymousNamespaces(func_name); - - fnamptr = strtack(fnamptr, func_name, fnambuf + MAX_FNAMBUF); - if (!fnamptr) - throw "Too many func names; increase MAX_FNAMBUF."; -} - -struct RVASorter -{ - bool operator()(const RVAEnt& e1, const RVAEnt& e2) - { - return e1.rva < e2.rva; - } -}; - -int -main(int argc, char** argv) -{ - long load_addr; - - if (argc < 3) { - printf("mapconv \n"); - return 0; - } - - // TODO: Choose a better default for the vdi file. - int ver = 20151002; - - if (!(f = fopen(argv[1], "r"))) { - printf("can't open listing file \"%s\"\n", argv[1]); - return 20; - } - - if (!(fo = fopen(argv[2], "wb"))) { - printf("can't open output file \"%s\"\n", argv[2]); - return 20; - } - - // Begin parsing file - - try { - line[0] = 0; - - // printf("Looking for segment list.\n"); - - if (!findline("Start Length")) - throw "can't find segment list"; - - // printf("Reading in segment list.\n"); - - while (readline()) { - long grp, start, len; - - if (3 != sscanf(line, "%lx:%lx %lx", &grp, &start, &len)) - break; - - if (strstr(line + 49, "CODE")) { - // printf("%04x:%08lx %08lx type code\n", grp, - // start, len); - - codeseg_flags |= 1 << grp; - - segbuf[segcnt][0] = start; - segbuf[segcnt][1] = len; - seggrp[segcnt] = grp; - ++segcnt; - } - } - - // printf("Looking for public symbol list.\n"); - - if (!findline("Publics by Value")) - throw "Can't find public symbol list."; - - readline(); - - // printf("Found public symbol list.\n"); - - while (readline()) { - long grp, start, rva; - char symname[4096]; - int i; - - if (4 != - sscanf(line, "%lx:%lx %4095s %lx", &grp, &start, symname, &rva)) - break; - - if (!(codeseg_flags & (1 << grp)) && - strcmp(symname, "___ImageBase")) - continue; - - RVAEnt entry = { rva, strdup(line) }; - - rvabuf.push_back(entry); - - // parsename(rva,symname); - } - - // printf("Looking for static symbol list.\n"); - - if (!findline("Static symbols")) - printf("WARNING: No static symbols found!\n"); - else { - readline(); - - while (readline()) { - long grp, start, rva; - char symname[4096]; - - if (4 != - sscanf( - line, "%lx:%lx %4095s %lx", &grp, &start, symname, &rva)) - break; - - if (!(codeseg_flags & (1 << grp))) - continue; - - RVAEnt entry = { rva, strdup(line) }; - - rvabuf.push_back(entry); - - // parsename(rva,symname); - } - } - - // printf("Sorting RVA entries...\n"); - - std::sort(rvabuf.begin(), rvabuf.end(), RVASorter()); - - // printf("Processing RVA entries...\n"); - - for (int i = 0; i < rvabuf.size(); i++) { - long grp, start, rva; - char symname[4096]; - - sscanf(rvabuf[i].line, - "%lx:%lx %4095s %lx", - &grp, - &start, - symname, - &rva); - - grpstart[grp] = rva - start; - - parsename(rva, symname); - } - - // printf("Processing segment entries...\n"); - - for (int i = 0; i < segcnt; i++) { - segbuf[i][0] += grpstart[seggrp[i]]; - // printf("\t#%-2d %08lx-%08lx\n", i+1, segbuf[i][0], - // segbuf[i][0]+segbuf[i][1]-1); - } - /* - printf("Raw statistics:\n"); - printf("\tRVA bytes: %ld\n", rvabuf.size()*4); - printf("\tFunc name bytes: %ld\n", fnamptr - fnambuf); - printf("\nPacking RVA data..."); fflush(stdout); - */ - std::vector::iterator itRVA = rvabuf.begin(), - itRVAEnd = rvabuf.end(); - std::vector rvaout; - long firstrva = (*itRVA++).rva; - long lastrva = firstrva; - - for (; itRVA != itRVAEnd; ++itRVA) { - long rvadiff = (*itRVA).rva - lastrva; - - lastrva += rvadiff; - - if (rvadiff & 0xF0000000) - rvaout.push_back((char)(0x80 | ((rvadiff >> 28) & 0x7F))); - if (rvadiff & 0xFFE00000) - rvaout.push_back((char)(0x80 | ((rvadiff >> 21) & 0x7F))); - if (rvadiff & 0xFFFFC000) - rvaout.push_back((char)(0x80 | ((rvadiff >> 14) & 0x7F))); - if (rvadiff & 0xFFFFFF80) - rvaout.push_back((char)(0x80 | ((rvadiff >> 7) & 0x7F))); - rvaout.push_back((char)(rvadiff & 0x7F)); - } - - // printf("%ld bytes\n", rvaout.size()); - - // dump data - - static const char header[64] = "symbolic debug information\r\n\x1A"; - - fwrite(header, 64, 1, fo); - - long t; - - t = ver; - fwrite(&t, 4, 1, fo); - - t = rvaout.size() + 4; - fwrite(&t, 4, 1, fo); - - t = fnamptr - fnambuf; - fwrite(&t, 4, 1, fo); - - t = segcnt; - fwrite(&t, 4, 1, fo); - - fwrite(&firstrva, 4, 1, fo); - fwrite(&rvaout[0], rvaout.size(), 1, fo); - fwrite(fnambuf, fnamptr - fnambuf, 1, fo); - fwrite(segbuf, segcnt * 8, 1, fo); - - // really all done - - if (fclose(fo)) - throw "output file close failed"; - - } catch (const char* s) { - fprintf(stderr, "%s: %s\n", argv[1], s); - } - - fclose(f); - - return 0; -} - -/* - * (c) 2002 Avery Lee - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ \ No newline at end of file diff --git a/NoteSkins/beat/default/metrics.ini b/NoteSkins/beat/default/metrics.ini index 68cb8da0ff..b35cf4ccb3 100644 --- a/NoteSkins/beat/default/metrics.ini +++ b/NoteSkins/beat/default/metrics.ini @@ -24,6 +24,7 @@ TapNoteNoteColorTextureCoordSpacingX=0 TapNoteNoteColorTextureCoordSpacingY=0 HoldHeadNoteColorTextureCoordSpacingX=0 HoldHeadNoteColorTextureCoordSpacingY=0 +TapFakeNoteOpacityMultiplier=0.25 [GhostArrowDim] NoneCommand= diff --git a/NoteSkins/common/common/metrics.ini b/NoteSkins/common/common/metrics.ini index 55211d495c..763b653c9b 100644 --- a/NoteSkins/common/common/metrics.ini +++ b/NoteSkins/common/common/metrics.ini @@ -76,6 +76,7 @@ HoldTailNoteColorTextureCoordSpacingY=0 HoldTailNoteColorCount=8 HoldTailNoteColorType=Denominator +TapFakeNoteOpacityMultiplier=0.25 UseStretchHolds=0 UseShrinkHolds=0 diff --git a/NoteSkins/dance/DivideByZero/metrics.ini b/NoteSkins/dance/DivideByZero/metrics.ini index da57f01ecd..0195d18f81 100644 --- a/NoteSkins/dance/DivideByZero/metrics.ini +++ b/NoteSkins/dance/DivideByZero/metrics.ini @@ -149,6 +149,8 @@ HoldHeadIsAboveWavyParts=1 HoldTailIsAboveWavyParts=1 HoldActiveIsAddLayer=0 +TapFakeNoteOpacityMultiplier=0.25 + #Edit this incase you want to make noteskin for reverse or both FlipHoldBodyWhenReverse=1 diff --git a/NoteSkins/dance/default/metrics.ini b/NoteSkins/dance/default/metrics.ini index 05c6f0a747..c7ae674852 100644 --- a/NoteSkins/dance/default/metrics.ini +++ b/NoteSkins/dance/default/metrics.ini @@ -36,6 +36,8 @@ TapFakeNoteColorTextureCoordSpacingY=.125 HoldHeadNoteColorTextureCoordSpacingX=0 HoldHeadNoteColorTextureCoordSpacingY=.125 +TapFakeNoteOpacityMultiplier=0.25 + [GhostArrowDim] InitCommand= NoneCommand= diff --git a/NoteSkins/instructions.txt b/NoteSkins/instructions.txt index b77aa998ee..cfa36b03f8 100644 --- a/NoteSkins/instructions.txt +++ b/NoteSkins/instructions.txt @@ -4,7 +4,7 @@ How to Install Noteskins: path in archive | extract to ------------------------|----------------------- -NoteSkins\dance\MyDance | StepMania root folder +NoteSkins\dance\MyDance | Etterna root folder dance\MyDance | NoteSkins folder MyDance | Whichever gametype folder (see Step 2) @@ -17,14 +17,7 @@ Name | Description dance | Dance Dance Revolution + Solo (3, 4, 6 and 8(Double) Panels) pump | Pump It Up (5, 3(Double), 10(Double)) kb7 | DJMax 7 Keys/O2Jam (6 Keys + 1 Center) -ez2 | Ez2Dancer (3 Panels with 2 Hands, 3 Panels with 4 Hands and 6 Panels with 4 Hands(Double)) -para | Para Para Paradise (5 Panels) -ds3ddx | Dance Station 3DDX (4 Panels with 4 Hands) beat | Beatmania (5, 7, 10(Double) and 14(double) Keys + Scratch) -maniax | Dance Maniax (4 and 8(Double) Hand Receptors) -techno | TechnoMotion (4, 5, 8, 8(Double), 10(Double) and 16(Double) Panels) popn | Pop'n Music (5 and 9 Keys) -lights | Lights (For Arcade Cab Lights, Unused) -karaoke | Karaoke (Unimplemented) 3) extract based on steps 1 and 2. diff --git a/NoteSkins/kb7/default/metrics.ini b/NoteSkins/kb7/default/metrics.ini index 6f1f91a104..64e756b5fd 100644 --- a/NoteSkins/kb7/default/metrics.ini +++ b/NoteSkins/kb7/default/metrics.ini @@ -30,6 +30,8 @@ TapNoteNoteColorTextureCoordSpacingY=0.125 HoldHeadNoteColorTextureCoordSpacingX=0 HoldHeadNoteColorTextureCoordSpacingY=0.125 +TapFakeNoteOpacityMultiplier=0.25 + [GhostArrowDim] NoneCommand= HitMineCommand=finishtweening;blend,'BlendMode_Add';diffuse,1,1,1,1;zoom,1;rotationz,0;smooth,0.3;rotationz,90;linear,0.3;rotationz,180;diffusealpha,0 diff --git a/NoteSkins/kb7/orbital/metrics.ini b/NoteSkins/kb7/orbital/metrics.ini index f9399725ee..bc2bd52880 100644 --- a/NoteSkins/kb7/orbital/metrics.ini +++ b/NoteSkins/kb7/orbital/metrics.ini @@ -30,6 +30,8 @@ TapNoteNoteColorTextureCoordSpacingY=0 HoldHeadNoteColorTextureCoordSpacingX=0.125 HoldHeadNoteColorTextureCoordSpacingY=0 +TapFakeNoteOpacityMultiplier=0.25 + [GhostArrowDim] NoneCommand= HitMineCommand=finishtweening;blend,'BlendMode_Add';diffuse,1,1,1,1;zoom,1;rotationz,0;smooth,0.3;rotationz,90;linear,0.3;rotationz,180;diffusealpha,0 diff --git a/NoteSkins/kb7/retrobar-iidx/metrics.ini b/NoteSkins/kb7/retrobar-iidx/metrics.ini index 9a306a981e..c1363ba369 100644 --- a/NoteSkins/kb7/retrobar-iidx/metrics.ini +++ b/NoteSkins/kb7/retrobar-iidx/metrics.ini @@ -21,6 +21,8 @@ TapLiftAdditionTextureCoordOffsetY=0 HoldHeadNoteColorTextureCoordSpacingX=0 HoldHeadNoteColorTextureCoordSpacingY=0 +TapFakeNoteOpacityMultiplier=0.25 + [ReceptorArrow] InitCommand=effectclock,"beat";diffuseramp;effectcolor1,color(".8,.8,.8,1");effectcolor2,color("1,1,1,1");effecttiming,.2,0,.8,0;effectoffset,.05 NoneCommand=finishtweening;zoom,.85;diffusealpha,.9;linear,.11;diffusealpha,1;zoom,1 diff --git a/NoteSkins/kb7/retrobar-o2jam/metrics.ini b/NoteSkins/kb7/retrobar-o2jam/metrics.ini index 9a306a981e..c1363ba369 100644 --- a/NoteSkins/kb7/retrobar-o2jam/metrics.ini +++ b/NoteSkins/kb7/retrobar-o2jam/metrics.ini @@ -21,6 +21,8 @@ TapLiftAdditionTextureCoordOffsetY=0 HoldHeadNoteColorTextureCoordSpacingX=0 HoldHeadNoteColorTextureCoordSpacingY=0 +TapFakeNoteOpacityMultiplier=0.25 + [ReceptorArrow] InitCommand=effectclock,"beat";diffuseramp;effectcolor1,color(".8,.8,.8,1");effectcolor2,color("1,1,1,1");effecttiming,.2,0,.8,0;effectoffset,.05 NoneCommand=finishtweening;zoom,.85;diffusealpha,.9;linear,.11;diffusealpha,1;zoom,1 diff --git a/NoteSkins/kb7/retrobar-razor/noteskin.ini b/NoteSkins/kb7/retrobar-razor/metrics.ini similarity index 76% rename from NoteSkins/kb7/retrobar-razor/noteskin.ini rename to NoteSkins/kb7/retrobar-razor/metrics.ini index cee2a32ca4..47ee8c53fe 100644 --- a/NoteSkins/kb7/retrobar-razor/noteskin.ini +++ b/NoteSkins/kb7/retrobar-razor/metrics.ini @@ -6,4 +6,5 @@ HoldHeadNoteColorTextureCoordSpacingX=0 HoldHeadNoteColorTextureCoordSpacingY=0 StartDrawingHoldBodyOffsetFromHead=0 StopDrawingHoldBodyOffsetFromTail=-16 -DrawHoldHeadForTapsOnSameRow=0 \ No newline at end of file +DrawHoldHeadForTapsOnSameRow=0 +TapFakeNoteOpacityMultiplier=0.25 \ No newline at end of file diff --git a/NoteSkins/kb7/retrobar-razor_o2/metrics.ini b/NoteSkins/kb7/retrobar-razor_o2/metrics.ini index cee2a32ca4..47ee8c53fe 100644 --- a/NoteSkins/kb7/retrobar-razor_o2/metrics.ini +++ b/NoteSkins/kb7/retrobar-razor_o2/metrics.ini @@ -6,4 +6,5 @@ HoldHeadNoteColorTextureCoordSpacingX=0 HoldHeadNoteColorTextureCoordSpacingY=0 StartDrawingHoldBodyOffsetFromHead=0 StopDrawingHoldBodyOffsetFromTail=-16 -DrawHoldHeadForTapsOnSameRow=0 \ No newline at end of file +DrawHoldHeadForTapsOnSameRow=0 +TapFakeNoteOpacityMultiplier=0.25 \ No newline at end of file diff --git a/NoteSkins/kb7/retrobar/metrics.ini b/NoteSkins/kb7/retrobar/metrics.ini index 822d89f31b..fba7ccd56a 100644 --- a/NoteSkins/kb7/retrobar/metrics.ini +++ b/NoteSkins/kb7/retrobar/metrics.ini @@ -6,6 +6,8 @@ StopDrawingHoldBodyOffsetFromTail=-32 HoldHeadNoteColorTextureCoordSpacingX=0 HoldHeadNoteColorTextureCoordSpacingY=0 +TapFakeNoteOpacityMultiplier=0.25 + [ReceptorArrow] InitCommand=effectclock,"beat";diffuseramp;effectcolor1,color(".8,.8,.8,1");effectcolor2,color("1,1,1,1");effecttiming,.2,0,.8,0;effectoffset,.05 NoneCommand=finishtweening;zoom,.85;diffusealpha,.9;linear,.11;diffusealpha,1;zoom,1 diff --git a/NoteSkins/pump/cmd-routine-p1/Center Hold Body active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p1/Center Hold Body active (doubleres) 6x1.png deleted file mode 100644 index 027e61ba9e..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/Center Hold Body active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/Center Hold BottomCap active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p1/Center Hold BottomCap active (doubleres) 6x1.png deleted file mode 100644 index b60ec4889a..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/Center Hold BottomCap active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/Center Roll Head Active (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p1/Center Roll Head Active (doubleres) 3x2.png deleted file mode 100644 index 627c7cdc57..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/Center Roll Head Active (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/Center Tap Note (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p1/Center Tap Note (doubleres) 3x2.png deleted file mode 100644 index 830bef30ea..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/Center Tap Note (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/DownLeft Hold Body active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p1/DownLeft Hold Body active (doubleres) 6x1.png deleted file mode 100644 index 19e60823a6..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/DownLeft Hold Body active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/DownLeft Hold BottomCap active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p1/DownLeft Hold BottomCap active (doubleres) 6x1.png deleted file mode 100644 index 4de5a87f52..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/DownLeft Hold BottomCap active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/DownLeft Roll Head Active (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p1/DownLeft Roll Head Active (doubleres) 3x2.png deleted file mode 100644 index 9e024e30aa..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/DownLeft Roll Head Active (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/DownLeft Tap Note (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p1/DownLeft Tap Note (doubleres) 3x2.png deleted file mode 100644 index 3893eb361a..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/DownLeft Tap Note (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/DownRight Hold Body active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p1/DownRight Hold Body active (doubleres) 6x1.png deleted file mode 100644 index 35e3a6b4f9..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/DownRight Hold Body active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/DownRight Hold BottomCap active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p1/DownRight Hold BottomCap active (doubleres) 6x1.png deleted file mode 100644 index 6ec0d1090a..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/DownRight Hold BottomCap active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/DownRight Roll Head Active (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p1/DownRight Roll Head Active (doubleres) 3x2.png deleted file mode 100644 index c536da0d20..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/DownRight Roll Head Active (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/DownRight Tap Note (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p1/DownRight Tap Note (doubleres) 3x2.png deleted file mode 100644 index 9ebe8145e8..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/DownRight Tap Note (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/NoteSkin.lua b/NoteSkins/pump/cmd-routine-p1/NoteSkin.lua deleted file mode 100644 index 31188532f3..0000000000 --- a/NoteSkins/pump/cmd-routine-p1/NoteSkin.lua +++ /dev/null @@ -1,11 +0,0 @@ -local Noteskin = ... or {} - -Noteskin.PartsToRotate = { - --["elemenu"] = true|false; - ["Roll Head Active"] = false, - ["Roll Head Inactive"] = false, - -- - ["Tap Note"] = false -} - -return Noteskin diff --git a/NoteSkins/pump/cmd-routine-p1/UpLeft Hold Body active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p1/UpLeft Hold Body active (doubleres) 6x1.png deleted file mode 100644 index 5a00447d2a..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/UpLeft Hold Body active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/UpLeft Hold BottomCap active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p1/UpLeft Hold BottomCap active (doubleres) 6x1.png deleted file mode 100644 index 0c94cb8562..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/UpLeft Hold BottomCap active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/UpLeft Roll Head Active (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p1/UpLeft Roll Head Active (doubleres) 3x2.png deleted file mode 100644 index 7ed2bc8c88..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/UpLeft Roll Head Active (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/UpLeft Tap Note (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p1/UpLeft Tap Note (doubleres) 3x2.png deleted file mode 100644 index 8be4cb6229..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/UpLeft Tap Note (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/UpRight Hold Body active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p1/UpRight Hold Body active (doubleres) 6x1.png deleted file mode 100644 index f0688e3a19..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/UpRight Hold Body active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/UpRight Hold BottomCap active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p1/UpRight Hold BottomCap active (doubleres) 6x1.png deleted file mode 100644 index 83dbb888b6..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/UpRight Hold BottomCap active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/UpRight Roll Head Active (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p1/UpRight Roll Head Active (doubleres) 3x2.png deleted file mode 100644 index 3eabd88761..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/UpRight Roll Head Active (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/UpRight Tap Note (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p1/UpRight Tap Note (doubleres) 3x2.png deleted file mode 100644 index 96f8e10b1e..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p1/UpRight Tap Note (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p1/metrics.ini b/NoteSkins/pump/cmd-routine-p1/metrics.ini deleted file mode 100644 index 169c86427b..0000000000 --- a/NoteSkins/pump/cmd-routine-p1/metrics.ini +++ /dev/null @@ -1,2 +0,0 @@ -[Global] -FallbackNoteSkin=cmd \ No newline at end of file diff --git a/NoteSkins/pump/cmd-routine-p2/Center Hold Body active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p2/Center Hold Body active (doubleres) 6x1.png deleted file mode 100644 index 2a4bbd8928..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/Center Hold Body active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/Center Hold BottomCap active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p2/Center Hold BottomCap active (doubleres) 6x1.png deleted file mode 100644 index 8bd3ced27f..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/Center Hold BottomCap active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/Center Roll Head Active (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p2/Center Roll Head Active (doubleres) 3x2.png deleted file mode 100644 index 6985db501c..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/Center Roll Head Active (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/Center Tap Note (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p2/Center Tap Note (doubleres) 3x2.png deleted file mode 100644 index 0da49d4422..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/Center Tap Note (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/DownLeft Hold Body active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p2/DownLeft Hold Body active (doubleres) 6x1.png deleted file mode 100644 index 893ebd022d..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/DownLeft Hold Body active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/DownLeft Hold BottomCap active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p2/DownLeft Hold BottomCap active (doubleres) 6x1.png deleted file mode 100644 index feed7868aa..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/DownLeft Hold BottomCap active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/DownLeft Roll Head Active (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p2/DownLeft Roll Head Active (doubleres) 3x2.png deleted file mode 100644 index 86d8e1231a..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/DownLeft Roll Head Active (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/DownLeft Tap Note (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p2/DownLeft Tap Note (doubleres) 3x2.png deleted file mode 100644 index 29351fc81a..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/DownLeft Tap Note (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/DownRight Hold Body active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p2/DownRight Hold Body active (doubleres) 6x1.png deleted file mode 100644 index 094c51758a..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/DownRight Hold Body active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/DownRight Hold BottomCap active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p2/DownRight Hold BottomCap active (doubleres) 6x1.png deleted file mode 100644 index 3b034b0bde..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/DownRight Hold BottomCap active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/DownRight Roll Head Active (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p2/DownRight Roll Head Active (doubleres) 3x2.png deleted file mode 100644 index 34ef3e8dfc..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/DownRight Roll Head Active (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/DownRight Tap Note (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p2/DownRight Tap Note (doubleres) 3x2.png deleted file mode 100644 index 075e78b98e..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/DownRight Tap Note (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/NoteSkin.lua b/NoteSkins/pump/cmd-routine-p2/NoteSkin.lua deleted file mode 100644 index 31188532f3..0000000000 --- a/NoteSkins/pump/cmd-routine-p2/NoteSkin.lua +++ /dev/null @@ -1,11 +0,0 @@ -local Noteskin = ... or {} - -Noteskin.PartsToRotate = { - --["elemenu"] = true|false; - ["Roll Head Active"] = false, - ["Roll Head Inactive"] = false, - -- - ["Tap Note"] = false -} - -return Noteskin diff --git a/NoteSkins/pump/cmd-routine-p2/UpLeft Hold Body active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p2/UpLeft Hold Body active (doubleres) 6x1.png deleted file mode 100644 index a704c7c45f..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/UpLeft Hold Body active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/UpLeft Hold BottomCap active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p2/UpLeft Hold BottomCap active (doubleres) 6x1.png deleted file mode 100644 index d4addbe4cd..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/UpLeft Hold BottomCap active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/UpLeft Roll Head Active (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p2/UpLeft Roll Head Active (doubleres) 3x2.png deleted file mode 100644 index 87a0affead..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/UpLeft Roll Head Active (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/UpLeft Tap Note (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p2/UpLeft Tap Note (doubleres) 3x2.png deleted file mode 100644 index 637c80b666..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/UpLeft Tap Note (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/UpRight Hold Body active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p2/UpRight Hold Body active (doubleres) 6x1.png deleted file mode 100644 index 57960e7465..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/UpRight Hold Body active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/UpRight Hold BottomCap active (doubleres) 6x1.png b/NoteSkins/pump/cmd-routine-p2/UpRight Hold BottomCap active (doubleres) 6x1.png deleted file mode 100644 index 0004a659cb..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/UpRight Hold BottomCap active (doubleres) 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/UpRight Roll Head Active (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p2/UpRight Roll Head Active (doubleres) 3x2.png deleted file mode 100644 index 13f56d7731..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/UpRight Roll Head Active (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/UpRight Tap Note (doubleres) 3x2.png b/NoteSkins/pump/cmd-routine-p2/UpRight Tap Note (doubleres) 3x2.png deleted file mode 100644 index e987866b4b..0000000000 Binary files a/NoteSkins/pump/cmd-routine-p2/UpRight Tap Note (doubleres) 3x2.png and /dev/null differ diff --git a/NoteSkins/pump/cmd-routine-p2/metrics.ini b/NoteSkins/pump/cmd-routine-p2/metrics.ini deleted file mode 100644 index 169c86427b..0000000000 --- a/NoteSkins/pump/cmd-routine-p2/metrics.ini +++ /dev/null @@ -1,2 +0,0 @@ -[Global] -FallbackNoteSkin=cmd \ No newline at end of file diff --git a/NoteSkins/pump/default/metrics.ini b/NoteSkins/pump/default/metrics.ini index 1feb9ab498..bd4970bc14 100644 --- a/NoteSkins/pump/default/metrics.ini +++ b/NoteSkins/pump/default/metrics.ini @@ -18,6 +18,8 @@ FlipHoldBodyWhenReverse=1 TopHoldAnchorWhenReverse=0 HoldActiveIsAddLayer=0 +TapFakeNoteOpacityMultiplier=0.25 + [Center] [DownLeft] diff --git a/NoteSkins/pump/delta-note/metrics.ini b/NoteSkins/pump/delta-note/metrics.ini index a081255a5c..9edcc0e71b 100644 --- a/NoteSkins/pump/delta-note/metrics.ini +++ b/NoteSkins/pump/delta-note/metrics.ini @@ -25,6 +25,8 @@ HoldHeadNoteColorTextureCoordSpacingX=0 HoldHeadNoteColorTextureCoordSpacingY=0.125 +TapFakeNoteOpacityMultiplier=0.25 + [Center] diff --git a/NoteSkins/pump/delta-routine-p1/Center Hold Body Active.png b/NoteSkins/pump/delta-routine-p1/Center Hold Body Active.png deleted file mode 100644 index 735fe759f7..0000000000 Binary files a/NoteSkins/pump/delta-routine-p1/Center Hold Body Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p1/Center Hold BottomCap Active.png b/NoteSkins/pump/delta-routine-p1/Center Hold BottomCap Active.png deleted file mode 100644 index 9125a50a37..0000000000 Binary files a/NoteSkins/pump/delta-routine-p1/Center Hold BottomCap Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p1/Center Tap Note 6x1.png b/NoteSkins/pump/delta-routine-p1/Center Tap Note 6x1.png deleted file mode 100644 index 3e37b6e373..0000000000 Binary files a/NoteSkins/pump/delta-routine-p1/Center Tap Note 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p1/DownLeft Hold Body Active.png b/NoteSkins/pump/delta-routine-p1/DownLeft Hold Body Active.png deleted file mode 100644 index f644a7de1c..0000000000 Binary files a/NoteSkins/pump/delta-routine-p1/DownLeft Hold Body Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p1/DownLeft Hold BottomCap Active.png b/NoteSkins/pump/delta-routine-p1/DownLeft Hold BottomCap Active.png deleted file mode 100644 index e2518bf6ce..0000000000 Binary files a/NoteSkins/pump/delta-routine-p1/DownLeft Hold BottomCap Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p1/DownLeft Tap Note 6x1.png b/NoteSkins/pump/delta-routine-p1/DownLeft Tap Note 6x1.png deleted file mode 100644 index 622c9eb456..0000000000 Binary files a/NoteSkins/pump/delta-routine-p1/DownLeft Tap Note 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p1/DownRight Hold Body Active.png b/NoteSkins/pump/delta-routine-p1/DownRight Hold Body Active.png deleted file mode 100644 index fff27e97d3..0000000000 Binary files a/NoteSkins/pump/delta-routine-p1/DownRight Hold Body Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p1/DownRight Hold BottomCap Active.png b/NoteSkins/pump/delta-routine-p1/DownRight Hold BottomCap Active.png deleted file mode 100644 index f8d8aed9ca..0000000000 Binary files a/NoteSkins/pump/delta-routine-p1/DownRight Hold BottomCap Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p1/NoteSkin.lua b/NoteSkins/pump/delta-routine-p1/NoteSkin.lua deleted file mode 100644 index f491625f5c..0000000000 --- a/NoteSkins/pump/delta-routine-p1/NoteSkin.lua +++ /dev/null @@ -1,28 +0,0 @@ -local Noteskin = ... or {} - -Noteskin.ElementRedirs = { - --["element"] = "redirected_element"; - ["Hold Head Active"] = "Tap Note", - ["Hold Head Inactive"] = "Tap Note", - ["Roll Head Active"] = "Roll Head Active", - ["Roll Head Inactive"] = "Roll Head Active", - ["Tap Fake"] = "Tap Note", - ["Tap Lift"] = "Tap Note", - -- - ["Hold Topcap Inactive"] = "Hold Topcap Active", - ["Hold Body Inactive"] = "Hold Body Active", - ["Hold Bottomcap Inactive"] = "Hold Bottomcap Active", - ["Hold Tail Inactive"] = "Hold Tail Active", - -- - ["Roll Topcap Active"] = "Hold Topcap Active", - ["Roll Body Active"] = "Hold Body Active", - ["Roll Bottomcap Active"] = "Hold Bottomcap Active", - ["Roll Tail Active"] = "Hold Tail Active", - -- - ["Roll Topcap Inactive"] = "Hold Topcap Active", - ["Roll Body Inactive"] = "Hold Body Active", - ["Roll Bottomcap Inactive"] = "Hold Bottomcap Active", - ["Roll Tail Inactive"] = "Hold Tail Active" -} - -return Noteskin diff --git a/NoteSkins/pump/delta-routine-p1/UpLeft Hold Body Active.png b/NoteSkins/pump/delta-routine-p1/UpLeft Hold Body Active.png deleted file mode 100644 index 1dd09bcb1d..0000000000 Binary files a/NoteSkins/pump/delta-routine-p1/UpLeft Hold Body Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p1/UpLeft Hold BottomCap Active.png b/NoteSkins/pump/delta-routine-p1/UpLeft Hold BottomCap Active.png deleted file mode 100644 index 4c5784eaae..0000000000 Binary files a/NoteSkins/pump/delta-routine-p1/UpLeft Hold BottomCap Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p1/UpLeft Tap Note 6x1.png b/NoteSkins/pump/delta-routine-p1/UpLeft Tap Note 6x1.png deleted file mode 100644 index 86d2363df0..0000000000 Binary files a/NoteSkins/pump/delta-routine-p1/UpLeft Tap Note 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p1/UpRight Hold Body Active.png b/NoteSkins/pump/delta-routine-p1/UpRight Hold Body Active.png deleted file mode 100644 index da97e3664b..0000000000 Binary files a/NoteSkins/pump/delta-routine-p1/UpRight Hold Body Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p1/UpRight Hold BottomCap Active.png b/NoteSkins/pump/delta-routine-p1/UpRight Hold BottomCap Active.png deleted file mode 100644 index 3cad61e30f..0000000000 Binary files a/NoteSkins/pump/delta-routine-p1/UpRight Hold BottomCap Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p1/metrics.ini b/NoteSkins/pump/delta-routine-p1/metrics.ini deleted file mode 100644 index ff043649c2..0000000000 --- a/NoteSkins/pump/delta-routine-p1/metrics.ini +++ /dev/null @@ -1,2 +0,0 @@ -[Global] -FallbackNoteSkin=delta \ No newline at end of file diff --git a/NoteSkins/pump/delta-routine-p2/Center Hold Body Active.png b/NoteSkins/pump/delta-routine-p2/Center Hold Body Active.png deleted file mode 100644 index 02a7e08cc6..0000000000 Binary files a/NoteSkins/pump/delta-routine-p2/Center Hold Body Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p2/Center Hold BottomCap Active.png b/NoteSkins/pump/delta-routine-p2/Center Hold BottomCap Active.png deleted file mode 100644 index 135279fb5e..0000000000 Binary files a/NoteSkins/pump/delta-routine-p2/Center Hold BottomCap Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p2/Center Tap Note 6x1.png b/NoteSkins/pump/delta-routine-p2/Center Tap Note 6x1.png deleted file mode 100644 index 2cc8313cd8..0000000000 Binary files a/NoteSkins/pump/delta-routine-p2/Center Tap Note 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p2/DownLeft Hold Body Active.png b/NoteSkins/pump/delta-routine-p2/DownLeft Hold Body Active.png deleted file mode 100644 index 29dbf5601e..0000000000 Binary files a/NoteSkins/pump/delta-routine-p2/DownLeft Hold Body Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p2/DownLeft Hold BottomCap Active.png b/NoteSkins/pump/delta-routine-p2/DownLeft Hold BottomCap Active.png deleted file mode 100644 index a557217b0c..0000000000 Binary files a/NoteSkins/pump/delta-routine-p2/DownLeft Hold BottomCap Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p2/DownLeft Tap Note 6x1.png b/NoteSkins/pump/delta-routine-p2/DownLeft Tap Note 6x1.png deleted file mode 100644 index 53cf2ce346..0000000000 Binary files a/NoteSkins/pump/delta-routine-p2/DownLeft Tap Note 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p2/DownRight Hold Body Active.png b/NoteSkins/pump/delta-routine-p2/DownRight Hold Body Active.png deleted file mode 100644 index 920485ed03..0000000000 Binary files a/NoteSkins/pump/delta-routine-p2/DownRight Hold Body Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p2/DownRight Hold BottomCap Active.png b/NoteSkins/pump/delta-routine-p2/DownRight Hold BottomCap Active.png deleted file mode 100644 index e14f0b2bdc..0000000000 Binary files a/NoteSkins/pump/delta-routine-p2/DownRight Hold BottomCap Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p2/NoteSkin.lua b/NoteSkins/pump/delta-routine-p2/NoteSkin.lua deleted file mode 100644 index f491625f5c..0000000000 --- a/NoteSkins/pump/delta-routine-p2/NoteSkin.lua +++ /dev/null @@ -1,28 +0,0 @@ -local Noteskin = ... or {} - -Noteskin.ElementRedirs = { - --["element"] = "redirected_element"; - ["Hold Head Active"] = "Tap Note", - ["Hold Head Inactive"] = "Tap Note", - ["Roll Head Active"] = "Roll Head Active", - ["Roll Head Inactive"] = "Roll Head Active", - ["Tap Fake"] = "Tap Note", - ["Tap Lift"] = "Tap Note", - -- - ["Hold Topcap Inactive"] = "Hold Topcap Active", - ["Hold Body Inactive"] = "Hold Body Active", - ["Hold Bottomcap Inactive"] = "Hold Bottomcap Active", - ["Hold Tail Inactive"] = "Hold Tail Active", - -- - ["Roll Topcap Active"] = "Hold Topcap Active", - ["Roll Body Active"] = "Hold Body Active", - ["Roll Bottomcap Active"] = "Hold Bottomcap Active", - ["Roll Tail Active"] = "Hold Tail Active", - -- - ["Roll Topcap Inactive"] = "Hold Topcap Active", - ["Roll Body Inactive"] = "Hold Body Active", - ["Roll Bottomcap Inactive"] = "Hold Bottomcap Active", - ["Roll Tail Inactive"] = "Hold Tail Active" -} - -return Noteskin diff --git a/NoteSkins/pump/delta-routine-p2/UpLeft Hold Body Active.png b/NoteSkins/pump/delta-routine-p2/UpLeft Hold Body Active.png deleted file mode 100644 index 3ee447e24a..0000000000 Binary files a/NoteSkins/pump/delta-routine-p2/UpLeft Hold Body Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p2/UpLeft Hold BottomCap Active.png b/NoteSkins/pump/delta-routine-p2/UpLeft Hold BottomCap Active.png deleted file mode 100644 index 5d91e66b41..0000000000 Binary files a/NoteSkins/pump/delta-routine-p2/UpLeft Hold BottomCap Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p2/UpLeft Tap Note 6x1.png b/NoteSkins/pump/delta-routine-p2/UpLeft Tap Note 6x1.png deleted file mode 100644 index c781ed8a1e..0000000000 Binary files a/NoteSkins/pump/delta-routine-p2/UpLeft Tap Note 6x1.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p2/UpRight Hold Body Active.png b/NoteSkins/pump/delta-routine-p2/UpRight Hold Body Active.png deleted file mode 100644 index c2fe6d4cd6..0000000000 Binary files a/NoteSkins/pump/delta-routine-p2/UpRight Hold Body Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p2/UpRight Hold BottomCap Active.png b/NoteSkins/pump/delta-routine-p2/UpRight Hold BottomCap Active.png deleted file mode 100644 index a5e8147041..0000000000 Binary files a/NoteSkins/pump/delta-routine-p2/UpRight Hold BottomCap Active.png and /dev/null differ diff --git a/NoteSkins/pump/delta-routine-p2/metrics.ini b/NoteSkins/pump/delta-routine-p2/metrics.ini deleted file mode 100644 index ff043649c2..0000000000 --- a/NoteSkins/pump/delta-routine-p2/metrics.ini +++ /dev/null @@ -1,2 +0,0 @@ -[Global] -FallbackNoteSkin=delta \ No newline at end of file diff --git a/NoteSkins/pump/delta/metrics.ini b/NoteSkins/pump/delta/metrics.ini index fe13a76055..7e948b3eda 100644 --- a/NoteSkins/pump/delta/metrics.ini +++ b/NoteSkins/pump/delta/metrics.ini @@ -18,6 +18,8 @@ FlipHoldBodyWhenReverse=1 TopHoldAnchorWhenReverse=0 HoldActiveIsAddLayer=0 +TapFakeNoteOpacityMultiplier=0.25 + [Center] [DownLeft] diff --git a/NoteSkins/pump/frame5p/metrics.ini b/NoteSkins/pump/frame5p/metrics.ini index e82927ca40..e988d562e1 100644 --- a/NoteSkins/pump/frame5p/metrics.ini +++ b/NoteSkins/pump/frame5p/metrics.ini @@ -8,3 +8,4 @@ HoldTopCapAnimationLength=0.333 HoldBottomCapAnimationLength=0.333 HoldBodyAnimationLength=0.333 HoldTailAnimationLength=0.333 +TapFakeNoteOpacityMultiplier=0.25 \ No newline at end of file diff --git a/NoteSkins/pump/rhythm/metrics.ini b/NoteSkins/pump/rhythm/metrics.ini index faaa880191..34d91eaea0 100644 --- a/NoteSkins/pump/rhythm/metrics.ini +++ b/NoteSkins/pump/rhythm/metrics.ini @@ -2,4 +2,5 @@ TapNoteNoteColorTextureCoordSpacingX=0 TapNoteNoteColorTextureCoordSpacingY=0.125 HoldHeadNoteColorTextureCoordSpacingX=0 -HoldHeadNoteColorTextureCoordSpacingY=0.125 \ No newline at end of file +HoldHeadNoteColorTextureCoordSpacingY=0.125 +TapFakeNoteOpacityMultiplier=0.25 \ No newline at end of file diff --git a/NoteSkins/pump/simple/metrics.ini b/NoteSkins/pump/simple/metrics.ini index e82927ca40..e988d562e1 100644 --- a/NoteSkins/pump/simple/metrics.ini +++ b/NoteSkins/pump/simple/metrics.ini @@ -8,3 +8,4 @@ HoldTopCapAnimationLength=0.333 HoldBottomCapAnimationLength=0.333 HoldBodyAnimationLength=0.333 HoldTailAnimationLength=0.333 +TapFakeNoteOpacityMultiplier=0.25 \ No newline at end of file diff --git a/README.md b/README.md index 54c7aaae12..f891030366 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,15 @@ Etterna is a cross-platform rhythm game similar to [Dance Dance Revolution](http ## Installing -### Windows and macOS +### Windows, macOS, and Linux -Head to the [Github Releases](https://github.com/etternagame/etterna/releases) page, and download the relevant file for your operating system. For Windows, run the installer, and you should be ready to go. For macOS, first follow the below instructions. *After* doing them, mount the DMG and copy the Etterna folder to a location of your choice. Run the executable, and you are ready to go. +Head to the [GitHub Releases](https://github.com/etternagame/etterna/releases) page, and download the relevant file for your operating system. + +For Windows, run the installer, and you should be ready to go. + +For macOS, first follow the below instructions. *After* doing them, mount the DMG and copy the Etterna folder to a location of your choice. Run the executable, and you are ready to go. + +For Linux, there should be no extra steps. If it does not work, try to follow the build instructions to install the necessary dependencies. ### macOS @@ -41,10 +47,6 @@ This macOS binary is not signed, so before it can be installed it must be de-qua `xattr -d com.apple.quarantine ./Etterna*.dmg` -### Linux - -Currently, the only supported way to play Etterna on a Linux based operating system is to install from source. Please follow the instructions in [Building](Docs/Building.md) to get started. - ## Building All details related to building are in the [Building.md](Docs/Building.md) file. Since Etterna is cross-platform, you should be able to build on any recent version of Windows, macOS, or Linux. @@ -58,7 +60,7 @@ Etterna uses Doxygen and LuaDoc. Both still need a lot of work before being havi ## Bug Reporting -We use Github's [issue tracker](https://github.com/etternagame/etterna/issues) for all faults found in the game. If you would like to report a bug, please click the `Issues` tab at the top of this page, and use the `Bug report` template. +We use GitHub's [issue tracker](https://github.com/etternagame/etterna/issues) for all faults found in the game. If you would like to report a bug, please click the `Issues` tab at the top of this page, and use the `Bug report` template. ## Contributing @@ -70,7 +72,7 @@ If there is something else you want to work on that we don't have listed here, f Etterna uses the MIT License, as is required since we are derivative of StepMania 5. See [LICENSE](LICENSE) for more details. -In short, you are free to modify, sell, distribute, and sublicense this project. We ask that you include a reference to this github repository in your derivative, and do not hold us liable when something breaks. +In short, you are free to modify, sell, distribute, and sublicense this project. We ask that you include a reference to this GitHub repository in your derivative, and do not hold us liable when something breaks. Etterna uses the [MAD library](http://www.underbit.com/products/mad/) and [FFMPEG codecs](https://www.ffmpeg.org/). Those libraries, when built, use the [GPL license](http://www.gnu.org). diff --git a/Themes/Rebirth/BGAnimations/ScreenCoreBundleSelect overlay/bundleDisplay.lua b/Themes/Rebirth/BGAnimations/ScreenCoreBundleSelect overlay/bundleDisplay.lua index 57a896fa8c..2f5426d552 100644 --- a/Themes/Rebirth/BGAnimations/ScreenCoreBundleSelect overlay/bundleDisplay.lua +++ b/Themes/Rebirth/BGAnimations/ScreenCoreBundleSelect overlay/bundleDisplay.lua @@ -52,6 +52,27 @@ local actuals = { IconExitHeight = ratios.IconExitHeight * SCREEN_HEIGHT, } +local translations = { + Bundle = THEME:GetString("BundleDownloader", "Bundle"), + Exit = THEME:GetString("BundleDownloader", "Exit"), + Megabytes = THEME:GetString("BundleDownloader", "Megabytes"), + KilobytesPerSecond = THEME:GetString("BundleDownloader", "KilobytesPerSecond"), + Downloading = THEME:GetString("BundleDownloader", "Downloading"), + PacksRemaining = THEME:GetString("BundleDownloader", "PacksRemaining"), + WelcomeInstruction = THEME:GetString("BundleDownloader", "WelcomeInstruction"), + DisconnectedAlert = THEME:GetString("BundleDownloader", "DisconnectedAlert"), + Novice = THEME:GetString("BundleDownloader", "Novice"), + NoviceDescription = THEME:GetString("BundleDownloader", "NoviceDescription"), + Beginner = THEME:GetString("BundleDownloader", "Beginner"), + BeginnerDescription = THEME:GetString("BundleDownloader", "BeginnerDescription"), + Intermediate = THEME:GetString("BundleDownloader", "Intermediate"), + IntermediateDescription = THEME:GetString("BundleDownloader", "IntermediateDescription"), + Advanced = THEME:GetString("BundleDownloader", "Advanced"), + AdvancedDescription = THEME:GetString("BundleDownloader", "AdvancedDescription"), + Expert = THEME:GetString("BundleDownloader", "Expert"), + ExpertDescription = THEME:GetString("BundleDownloader", "ExpertDescription"), +} + local infoTextSize = 0.37 local progressTextSize = 0.35 local bundleNameTextSize = 0.4 @@ -65,27 +86,27 @@ local function bundleList() { Name = "Novice", Color = COLORS:getColor("downloader", "Bundle1Easiest"), - Description = "A bundle aimed at people who are entirely new to rhythm games.\nMostly single notes throughout the song and very little pattern complexity.", + Description = translations["NoviceDescription"], }, { Name = "Beginner", Color = COLORS:getColor("downloader", "Bundle2Easy"), - Description = "A bundle for those who have formed some muscle memory.\nJumps (2 note chords) are introduced; some technical patterns start to appear.", + Description = translations["BeginnerDescription"], }, { Name = "Intermediate", Color = COLORS:getColor("downloader", "Bundle3Medium"), - Description = "A bundle for players who can confidently play complex patterns.\nJumpstream/handstream, very technical patterns, and jacks are common.", + Description = translations["IntermediateDescription"], }, { Name = "Advanced", Color = COLORS:getColor("downloader", "Bundle4Hard"), - Description = "A bundle for advanced players.\nDumps are introduced. Very fast patterns in stamina intensive and complex files.", + Description = translations["AdvancedDescription"], }, { Name = "Expert", Color = COLORS:getColor("downloader", "Bundle5Hardest"), - Description = "A bundle for veterans.\nSome of the hardest songs the game has to offer. Nothing is off-limits.", + Description = translations["ExpertDescription"], }, } @@ -147,9 +168,9 @@ local function bundleList() SetCommand = function(self) if bundleUserdata.TotalSize == 0 then -- odd situation. maybe the api is down? no connection? - self:settextf("%s Bundle", bundle.Name) + self:settextf("%s %s", translations[bundle.Name], translations["Bundle"]) else - self:settextf("%s Bundle (%dMB)", bundle.Name, bundleUserdata.TotalSize) + self:settextf("%s %s (%d%s)", translations[bundle.Name], translations["Bundle"], bundleUserdata.TotalSize, translations["Megabytes"]) end end, CoreBundlesRefreshedMessageCommand = function(self) @@ -233,7 +254,7 @@ local t = Def.ActorFrame { self:zoom(infoTextSize) self:maxheight((actuals.InfoHeight - (actuals.InfoVerticalBuffer*2)) / infoTextSize) self:wrapwidthpixels((actuals.InfoWidth - (actuals.InfoHorizontalBuffer*2)) / infoTextSize) - self:settext("Welcome to Etterna!\nLet's start by installing some songs. Click the button that corresponds to your skill level and the installation will proceed automatically.") + self:settext(translations["WelcomeInstruction"]) end, }, }, @@ -256,7 +277,7 @@ local t = Def.ActorFrame { Name = "DisconnectedAlert", InitCommand = function(self) self:visible(false) - self:settext("Server pack listing is empty.\nIs the API down?\nIs your network connection down?\nYou may have to install songs manually.") + self:settext(translations["DisconnectedAlert"]) self:xy(actuals.MainDisplayWidth/2, actuals.MainDisplayHeight/2) self:maxheight(actuals.MainDisplayHeight / disconnectedTextSize) self:maxwidth(actuals.MainDisplayWidth / disconnectedTextSize) @@ -296,7 +317,7 @@ local t = Def.ActorFrame { end, MouseOverCommand = function(self, params) self:diffusealpha(buttonHoverAlpha) - TOOLTIP:SetText("Exit") + TOOLTIP:SetText(translations["Exit"]) TOOLTIP:Show() end, MouseOutCommand = function(self, params) @@ -347,9 +368,23 @@ local t = Def.ActorFrame { end, UpdateProgressCommand = function(self, params) if params.filesRemaining > 0 then - self:settextf("Downloading ... (%5.2f%% %dKB/s %d packs remaining)", params.progress / params.size * 100, params.kbsec, params.filesRemaining) + self:settextf( + "%s ... (%5.2f%% %d%s %d %s)", + translations["Downloading"], + params.progress / params.size * 100, + params.kbsec, + translations["KilobytesPerSecond"], + params.filesRemaining, + translations["PacksRemaining"] + ) else - self:settextf("Downloading ... (%5.2f%% %dKB/s)", params.progress / params.size * 100, params.kbsec) + self:settextf( + "%s ... (%5.2f%% %d%s)", + translations["Downloading"], + params.progress / params.size * 100, + params.kbsec, + translations["KilobytesPerSecond"] + ) end end, }, diff --git a/Themes/Rebirth/BGAnimations/ScreenEvaluation decorations/mainDisplay.lua b/Themes/Rebirth/BGAnimations/ScreenEvaluation decorations/mainDisplay.lua index 7cedd02001..8966a878b7 100644 --- a/Themes/Rebirth/BGAnimations/ScreenEvaluation decorations/mainDisplay.lua +++ b/Themes/Rebirth/BGAnimations/ScreenEvaluation decorations/mainDisplay.lua @@ -4,29 +4,38 @@ local pss = STATSMAN:GetCurStageStats():GetPlayerStageStats() local chosenScore local mostRecentScore = SCOREMAN:GetMostRecentScore() local screen - -local function evalInput(event) - if event.type == "InputEventType_FirstPress" then - local btn = event.GameButton - if btn ~= nil then - if btn == "EffectUp" then - -- judge window increase - judgeSetting = clamp(judgeSetting + 1, 4, 9) - MESSAGEMAN:Broadcast("JudgeWindowChanged") - elseif btn == "EffectDown" then - -- judge window decrease - judgeSetting = clamp(judgeSetting - 1, 4, 9) - MESSAGEMAN:Broadcast("JudgeWindowChanged") - end - end - end -end +local usingCustomWindows = false local t = Def.ActorFrame { Name = "MainDisplayFile", BeginCommand = function(self) screen = SCREENMAN:GetTopScreen() - screen:AddInputCallback(evalInput) + screen:AddInputCallback(function(event) + if event.type == "InputEventType_FirstPress" then + local btn = event.GameButton + if btn ~= nil then + local dir = 0 + if btn == "EffectUp" then + -- judge window increase + dir = 1 + elseif btn == "EffectDown" then + -- judge window decrease + dir = -1 + end + + if dir ~= 0 and not usingCustomWindows then + judgeSetting = clamp(judgeSetting + dir, 4, 9) + MESSAGEMAN:Broadcast("JudgeWindowChanged") + elseif dir ~= 0 and usingCustomWindows then + self:playcommand("MoveCustomWindowIndex", {direction = dir}) + end + + if btn == "Coin" then + self:playcommand("ToggleCustomWindows") + end + end + end + end) updateDiscordStatus(true) end, OnCommand = function(self) @@ -40,9 +49,9 @@ local t = Def.ActorFrame { local forcedScreenEntryJudgeWindow = nil if PREFSMAN:GetPreference("SortBySSRNormPercent") then forcedScreenEntryJudgeWindow = 4 - -- update replaysnapshots and pss for current score being rejudged to j4 - screen:SetPlayerStageStatsFromReplayData(pss, ms.JudgeScalers[forcedScreenEntryJudgeWindow], score) end + -- update replaysnapshots and pss for current score being rejudged to whatever judge + screen:RescoreReplay(pss, ms.JudgeScalers[forcedScreenEntryJudgeWindow or judgeSetting], score, usingCustomWindows and currentCustomWindowConfigUsesOldestNoteFirst()) --- propagate set command through children with the song self:playcommand("Set", { @@ -60,9 +69,28 @@ local t = Def.ActorFrame { judgeSetting = params.judgeSetting end + -- for custom windows we have to recalculate everything once to update normal values and then recalculate again for custom windows itself + if usingCustomWindows and params.score ~= nil and chosenScore ~= nil and params.score ~= chosenScore then + usingCustomWindows = false + screen:RescoreReplay(pss, ms.JudgeScalers[judgeSetting], params.score, false) + --- update all relevant information according to the given score + -- should work with offset plot as well as all regular information on this screen + -- this is intended for use only with replays but may partially work without it + chosenScore = params.score + self:playcommand("Set", { + song = GAMESTATE:GetCurrentSong(), + steps = GAMESTATE:GetCurrentSteps(), + score = params.score, + judgeSetting = params.judgeSetting, + rejudged = params.rejudged, -- optional param to know if need to reload offset plot + usingCustomWindows = false, + }) + usingCustomWindows = true + end + -- we assume the score has a replay - -- recalculate playerstagestats using the replay - screen:SetPlayerStageStatsFromReplayData(pss, ms.JudgeScalers[judgeSetting], params.score) + -- recalculate all stats using the replay + screen:RescoreReplay(pss, ms.JudgeScalers[judgeSetting], params.score, usingCustomWindows and currentCustomWindowConfigUsesOldestNoteFirst()) chosenScore = params.score @@ -75,6 +103,7 @@ local t = Def.ActorFrame { score = params.score, judgeSetting = params.judgeSetting, rejudged = params.rejudged, -- optional param to know if need to reload offset plot + usingCustomWindows = usingCustomWindows, }) end, JudgeWindowChangedMessageCommand = function(self) @@ -87,6 +116,50 @@ local t = Def.ActorFrame { rejudged = true, }) end, + ToggleCustomWindowsMessageCommand = function(self) + usingCustomWindows = not usingCustomWindows + + if usingCustomWindows then + loadCurrentCustomWindowConfig() + screen:RescoreReplay(pss, 1, chosenScore, currentCustomWindowConfigUsesOldestNoteFirst()) + self:playcommand("Set", { + song = GAMESTATE:GetCurrentSong(), + steps = GAMESTATE:GetCurrentSteps(), + score = chosenScore, + judgeSetting = judgeSetting, + rejudged = true, + usingCustomWindows = usingCustomWindows, + }) + else + unloadCustomWindowConfig() + self:playcommand("UpdateScore", { + judgeSetting = judgeSetting, + rejudged = true, + score = chosenScore, + usingCustomWindows = usingCustomWindows, + }) + end + + end, + MoveCustomWindowIndexMessageCommand = function(self, params) + if not usingCustomWindows then return end + + moveCustomWindowConfigIndex(params.direction) + loadCurrentCustomWindowConfig() + screen:RescoreReplay(pss, 1, chosenScore, currentCustomWindowConfigUsesOldestNoteFirst()) + self:playcommand("Set", { + song = GAMESTATE:GetCurrentSong(), + steps = GAMESTATE:GetCurrentSteps(), + score = chosenScore, + judgeSetting = judgeSetting, + rejudged = true, + usingCustomWindows = usingCustomWindows, + }) + + end, + EndCommand = function(self) + unloadCustomWindowConfig() + end, LoginMessageCommand = function(self) self:playcommand("UpdateLoginStatus") end, @@ -231,6 +304,39 @@ local actuals = { OffsetPlotWidth = ratios.OffsetPlotWidth * SCREEN_WIDTH, } +local translations = { + Title = THEME:GetString("ScreenEvaluation", "Title"), + ReplayTitle = THEME:GetString("ScreenEvaluation", "ReplayTitle"), + Mean = THEME:GetString("ScreenEvaluation", "Mean"), + StandardDeviation = THEME:GetString("ScreenEvaluation", "StandardDeviation"), + Largest = THEME:GetString("ScreenEvaluation", "Largest"), + LeftCBs = THEME:GetString("ScreenEvaluation", "LeftCBs"), + MiddleCBs = THEME:GetString("ScreenEvaluation", "MiddleCBs"), + RightCBs = THEME:GetString("ScreenEvaluation", "RightCBs"), + CBsPerColumn = THEME:GetString("ScreenEvaluation", "CBsPerColumn"), + Column = THEME:GetString("ScreenEvaluation", "Column"), + Justice = THEME:GetString("ScreenEvaluation", "Justice"), +} + +-- require that the banner ratio is 3.2 for consistency +local nonstandardBannerSizing = false +do + local rat = actuals.BannerWidth / actuals.BannerHeight + if rat ~= 3.2 then + local possibleHeight = actuals.BannerWidth / 3.2 + if possibleHeight > actuals.BannerHeight then + -- height stays, width moves + actuals.BannerWidth = actuals.BannerHeight * 3.2 + else + -- width stays, height moves + actuals.BannerHeight = actuals.BannerWidth / 3.2 + end + -- this will produce a visible gap but the ratio will stay the same + nonstandardBannerSizing = true + end + actuals.BannerAreaHeight = ratios.BannerHeight * SCREEN_HEIGHT +end + -- constant list of judgments for rescoring purposes -- for the most part this list is the same as the one below but remains separate just "in case" local tapJudgments = { @@ -313,7 +419,7 @@ local function subTypeStats() self:halign(0):valign(0) self:zoom(subTypeTextZoom) self:maxwidth((actuals.SubTypeNumberCenter - subTypeTextBump - actuals.SubTypeNumberWidth / 2) / subTypeTextZoom - textzoomFudge) - self:settext(rdr) + self:settext(THEME:GetString("RadarCategory", rdr)) registerActorToColorConfigElement(self, "main", "PrimaryText") end }, @@ -380,19 +486,12 @@ local function subTypeStats() end local function accuracyStats() - local statStrings = { - "RA", -- Ridiculous Attack - Ratio of J7 Marvelous to J7 Perfect - "MA", -- Marvelous Attack - Ratio of Marvelous to Perfects - "PA", -- Perfect Attack - Ratio of Perfects to Greats - "Longest MFC", -- Longest streak of Marvelous or better - "Longest PFC", -- Longest streak of Perfect or better - } local statTypes = { - "EvalRA", - "EvalMA", - "EvalPA", - "EvalLongestMFC", - "EvalLongestPFC", + "EvalRA", -- Ridiculous Attack - Ratio of J7 Marvelous to J7 Perfect + "EvalMA", -- Marvelous Attack - Ratio of Marvelous to Perfects + "EvalPA", -- Perfect Attack - Ratio of Perfects to Greats + "EvalLongestMFC", -- Longest streak of Marvelous or better + "EvalLongestPFC", -- Longest streak of Perfect or better } local statData = { 0, -- Ridiculous divided by Marvelous @@ -412,8 +511,9 @@ local function accuracyStats() -- calculates the statData based on the given score local function calculateStatData(score) - local offsetTable = score:GetOffsetVector() - local typeTable = score:GetTapNoteTypeVector() + local replay = REPLAYS:GetActiveReplay() + local offsetTable = usingCustomWindows and replay:GetOffsetVector() or score:GetOffsetVector() + local typeTable = usingCustomWindows and replay:GetTapNoteTypeVector() or score:GetTapNoteTypeVector() -- must match statData above local output = { @@ -428,10 +528,17 @@ local function accuracyStats() return output end - local ridicThreshold = ms.JudgeScalers[judgeSetting] * 11.25 -- this is the J7 Marvelous window - local marvThreshold = ms.JudgeScalers[judgeSetting] * 22.5 -- J4 Marvelous window - local perfThreshold = ms.JudgeScalers[judgeSetting] * 45 -- J4 Perfect window - local greatThreshold = ms.JudgeScalers[judgeSetting] * 90 -- J4 Great window + local windowtable = usingCustomWindows and getCurrentCustomWindowConfigJudgmentWindowTable() or { + TapNoteScore_W1 = 22.5 * ms.JudgeScalers[judgeSetting], + TapNoteScore_W2 = 45 * ms.JudgeScalers[judgeSetting], + TapNoteScore_W3 = 90 * ms.JudgeScalers[judgeSetting], + } + windowtable["TapNoteScore_W0"] = windowtable["TapNoteScore_W1"] / 2 + + local ridicThreshold = windowtable["TapNoteScore_W0"] -- this is the J7 Marvelous window + local marvThreshold = windowtable["TapNoteScore_W1"] -- J4 Marvelous window + local perfThreshold = windowtable["TapNoteScore_W2"] -- J4 Perfect window + local greatThreshold = windowtable["TapNoteScore_W3"] -- J4 Great window local currentRFC = 0 local currentMFC = 0 local currentPFC = 0 @@ -527,11 +634,10 @@ local function accuracyStats() end } local function makeLine(i) - local statname = statStrings[i] return Def.ActorFrame { Name = "Stat_"..i, InitCommand = function(self) - self:y((actuals.StatTextAllottedSpace / (#statStrings - 1)) * (i-1)) + self:y((actuals.StatTextAllottedSpace / (#statTypes - 1)) * (i-1)) end, Def.RollingNumbers { Name = "Number", @@ -557,7 +663,7 @@ local function accuracyStats() } end - for i = 1, #statStrings do + for i = 1, #statTypes do t[#t+1] = makeLine(i) end return t @@ -567,12 +673,12 @@ local function calculatedStats() -- list of stats -- do not allow this list to be shorter than 2 in length local statStrings = { - "Mean", - "Sd", - "Largest", - "Left CBs", - "Middle CBs", -- skip this index for even column types - "Right CBs", + translations["Mean"], + translations["StandardDeviation"], + translations["Largest"], + translations["LeftCBs"], + translations["MiddleCBs"], -- skip this index for even column types + translations["RightCBs"], } -- RollingNumber types in metrics @@ -602,8 +708,9 @@ local function calculatedStats() local cbInfo = {0,0,0,0} -- per column cb info local function calculateStatData(score, numColumns) - local tracks = score:GetTrackVector() - local offsetTable = score:GetOffsetVector() + local replay = REPLAYS:GetActiveReplay() + local tracks = usingCustomWindows and replay:GetTrackVector() or score:GetTrackVector() + local offsetTable = usingCustomWindows and replay:GetOffsetVector() or score:GetOffsetVector() local middleColumn = numColumns / 2 @@ -626,7 +733,8 @@ local function calculatedStats() return output, cbInfo end - local cbThreshold = ms.JudgeScalers[judgeSetting] * 90 + + local cbThreshold = usingCustomWindows and getCurrentCustomWindowConfigJudgmentWindowTable()["TapNoteScore_W3"] or (ms.JudgeScalers[judgeSetting] * 90) local leftCB = 0 local middleCB = 0 local rightCB = 0 @@ -757,9 +865,9 @@ local function calculatedStats() RolloverUpdateCommand = function(self, params) -- hovering if params.update == "over" then - local cbstr = {"CBs Per Column", "\n"} + local cbstr = {translations["CBsPerColumn"], "\n"} for _ = 1, #cbInfo do - cbstr[#cbstr+1] = string.format("Column %d: %d", _, cbInfo[_]) + cbstr[#cbstr+1] = string.format("%s %d: %d", translations["Column"], _, cbInfo[_]) cbstr[#cbstr+1] = "\n" end cbstr[#cbstr] = nil @@ -814,6 +922,7 @@ local function wifePercentDisplay() end, SetCommand = function(self, params) if params.score ~= nil then + if usingCustomWindows then return end local ver = params.score:GetWifeVers() local percent = params.score:GetWifeScore() * 100 decimals = 2 @@ -823,8 +932,8 @@ local function wifePercentDisplay() ver = 3 end -- wife version string - local ws = "W"..ver.." J" - ws = ws .. (judgeSetting ~= 9 and judgeSetting or "ustice") + local ws = "W"..ver.." " + ws = ws .. (judgeSetting ~= 9 and "J"..judgeSetting or translations["Justice"]) -- scores over 99% should show more decimals if percent > 99 or isOver(self) then decimals = 4 @@ -848,7 +957,87 @@ local function wifePercentDisplay() self:playcommand("UpdateParameters", {decimals = nothoverdecimals}) end self:playcommand("UpdateText") - end + end, + MouseDownCommand = function(self) + MESSAGEMAN:Broadcast("ToggleCustomWindows") + end, + } +end + +local function customScoringDisplay() + -- internal value storage defaults + local value = 0 + local decimals = 2 + local stringformat = "%05."..decimals.."f%% [%s]" + + -- """constants""" + local nothoverdecimals = 2 -- when not hovering + local hoverdecimals = 4 -- when hovering + local infostr = "" -- example: W3 J4 + + return UIElements.TextToolTip(1, 1, "Common Large") .. { + Name = "CustomPercent", + InitCommand = function(self) + self:halign(1):valign(1) + self:zoom(scoreInfoTextSize) + self:maxwidth(actuals.RightHalfRightAlignLeftGap / 2 / scoreInfoTextSize - textzoomFudge) + end, + UpdateParametersCommand = function(self, params) + if params.decimals ~= nil then + decimals = params.decimals + stringformat = "%05."..decimals.."f%% [%s]" + end + if params.infostr ~= nil then + infostr = params.infostr + end + if params.value ~= nil then + value = params.value + end + end, + UpdateTextCommand = function(self) + self:settextf(stringformat, notShit.floor(value, decimals), infostr) + end, + ColorConfigUpdatedMessageCommand = function(self) + self:playcommand("Set") + end, + SetCommand = function(self, params) + if params.score ~= nil then + + self:visible(usingCustomWindows) + if not usingCustomWindows then return end + + local lastSnapshot = REPLAYS:GetActiveReplay():GetLastReplaySnapshot() + local percent = lastSnapshot:GetWifePercent() * 100 + local ss = getCurrentCustomWindowConfigName() + + -- scores over 99% should show more decimals + if percent > 99 or isOver(self) then + decimals = 4 + end + local pg = notShit.floor(percent, decimals) + local grade = GetGradeFromPercent(pg / 100) + self:diffuse(colorByGrade(grade)) + self:playcommand("UpdateParameters", {decimals = decimals, infostr = ss, value = percent}) + self:playcommand("UpdateText") + else + self:settext("") + end + end, + MouseOverCommand = function(self) self:playcommand("RolloverUpdate",{update = "over"}) end, + MouseOutCommand = function(self) self:playcommand("RolloverUpdate",{update = "out"}) end, + RolloverUpdateCommand = function(self, params) + -- hovering + if params.update == "over" then + self:playcommand("UpdateParameters", {decimals = hoverdecimals}) + elseif params.update == "out" then + self:playcommand("UpdateParameters", {decimals = nothoverdecimals}) + end + self:playcommand("UpdateText") + end, + MouseDownCommand = function(self, params) + if self:IsInvisible() then return end + MESSAGEMAN:Broadcast("MoveCustomWindowIndex", {direction = params.event == "DeviceButton_left mouse button" and 1 or -1}) + end, } end @@ -920,6 +1109,11 @@ t[#t+1] = Def.ActorFrame { self:xy(actuals.BannerLeftGap, actuals.BannerUpperGap) self:valign(0):halign(0) self:scaletoclipped(actuals.BannerWidth, actuals.BannerHeight) + if nonstandardBannerSizing then + -- when the banner has been resized to an unexpected size, to fit the 3.2 ratio, reposition it + -- this movement centers it in the area provided + self:addy((actuals.BannerAreaHeight - actuals.BannerHeight) / 2) + end end, SetCommand = function(self, params) self:finishtweening() @@ -927,7 +1121,9 @@ t[#t+1] = Def.ActorFrame { self:diffusealpha(1) if params.song then local bnpath = params.song:GetBannerPath() - if not bnpath then + if not showBanners() then + self:visible(false) + elseif not bnpath then bnpath = THEME:GetPathG("Common", "fallback banner") self:visible(false) else @@ -944,6 +1140,12 @@ t[#t+1] = Def.ActorFrame { InitCommand = function(self) self:valign(0):halign(0) self:xy(actuals.GraphLeftGap, actuals.BannerUpperGap + actuals.GraphBannerGap + actuals.BannerHeight) + if nonstandardBannerSizing then + -- when the banner has been resized to an unexpected size, to fit the 3.2 ratio, reposition it + -- this movement centers it in the area provided + self:addy((actuals.BannerAreaHeight - actuals.BannerHeight) / 2) + end + -- due to reasons, the sizing for this is in metrics [GraphDisplay] -- we override them with the following zoomto -- so the ones in metrics can be anything.... @@ -966,6 +1168,12 @@ t[#t+1] = Def.ActorFrame { InitCommand = function(self) self:valign(0):halign(0) self:xy(actuals.GraphLeftGap, actuals.BannerUpperGap + actuals.GraphBannerGap + actuals.BannerHeight + actuals.LifeGraphHeight) + if nonstandardBannerSizing then + -- when the banner has been resized to an unexpected size, to fit the 3.2 ratio, reposition it + -- this movement centers it in the area provided + self:addy((actuals.BannerAreaHeight - actuals.BannerHeight) / 2) + end + -- due to reasons, the sizing for this is in metrics [ComboGraph] -- we dont override them here because the combo text is broken by the zoom -- self:zoomto(actuals.GraphWidth, actuals.ComboGraphHeight) @@ -996,7 +1204,7 @@ t[#t+1] = Def.ActorFrame { if not ss:GetLivePlay() then mstr = screen:GetReplayModifiers() end - self:settext(mstr) + self:settext(getModifierTranslations(mstr)) end }, LoadActorWithParams("../judgmentBars", { @@ -1034,12 +1242,13 @@ t[#t+1] = Def.ActorFrame { self:xy(actuals.RightHalfLeftGap, actuals.LipHeight / 2) self:halign(0) self:zoom(titleTextSize) + self:maxwidth(actuals.OffsetPlotWidth / titleTextSize - textzoomFudge) registerActorToColorConfigElement(self, "main", "PrimaryText") if GAMESTATE:GetCurrentSteps() ~= nil then local st = THEME:GetString("StepsDisplay StepsType", ToEnumShortString(GAMESTATE:GetCurrentSteps():GetStepsType())) - self:settextf("%s Results", st) + self:settextf("%s %s", st, translations["Title"]) else - self:settext("Results") + self:settext(translations["Title"]) end end, SetCommand = function(self, params) @@ -1054,9 +1263,9 @@ t[#t+1] = Def.ActorFrame { -- but view eval/replays also are mostrecentscores, so check the name -- the name is set for scores set during this session if mostRecentScore and params.score:GetName() == "#P1#" and params.score:GetScoreKey() == mostRecentScore:GetScoreKey() then - self:settext(stStr.."Results") + self:settext(stStr..translations["Title"]) else - self:settext(stStr.."Replay Results") + self:settext(stStr..translations["ReplayTitle"]) end end end @@ -1079,7 +1288,14 @@ t[#t+1] = Def.ActorFrame { self:maxwidth(actuals.RightHalfRightAlignLeftGap / 4 * 3 / songInfoTextSize - textzoomFudge) self:settext(GAMESTATE:GetCurrentSong():GetDisplayMainTitle()) registerActorToColorConfigElement(self, "main", "PrimaryText") - end + end, + SetCommand = function(self) + if usingCustomWindows then + self:maxwidth(actuals.RightHalfRightAlignLeftGap / 2 / songInfoTextSize - textzoomFudge) + else + self:maxwidth(actuals.RightHalfRightAlignLeftGap / 4 * 3 / songInfoTextSize - textzoomFudge) + end + end, }, LoadFont("Common Large") .. { Name = "SongArtist", @@ -1139,6 +1355,9 @@ t[#t+1] = Def.ActorFrame { self:maxwidth(actuals.RightHalfRightAlignLeftGap / 4 / scoreInfoTextSize - textzoomFudge) end, SetCommand = function(self, params) + self:visible(not usingCustomWindows) + if usingCustomWindows then return end + if params.score ~= nil then local percent = params.score:GetWifeScore() * 100 if params.judgeSetting ~= nil then @@ -1153,6 +1372,15 @@ t[#t+1] = Def.ActorFrame { else self:settext("") end + end, + }, + + -- this replaces the grade when custom window scoring is turned on + -- by default it is turned off + customScoringDisplay() .. { + InitCommand = function(self) + self:y(-actuals.GradeLowerGap) + self:visible(false) end }, @@ -1212,17 +1440,18 @@ t[#t+1] = Def.ActorFrame { SetCommand = function(self, params) if params.score ~= nil and params.steps ~= nil then if params.score:HasReplayData() then - local offsets = params.score:GetOffsetVector() + local replay = REPLAYS:GetActiveReplay() + local offsets = usingCustomWindows and replay:GetOffsetVector() or params.score:GetOffsetVector() -- for online offset vectors a 180 offset is a miss for i, o in ipairs(offsets) do if o >= 180 then offsets[i] = 1000 end end - local tracks = params.score:GetTrackVector() - local types = params.score:GetTapNoteTypeVector() - local noterows = params.score:GetNoteRowVector() - local holds = params.score:GetHoldNoteVector() + local tracks = usingCustomWindows and replay:GetTrackVector() or params.score:GetTrackVector() + local types = usingCustomWindows and replay:GetTapNoteTypeVector() or params.score:GetTapNoteTypeVector() + local noterows = usingCustomWindows and replay:GetNoteRowVector() or params.score:GetNoteRowVector() + local holds = usingCustomWindows and replay:GetHoldNoteVector() or params.score:GetHoldNoteVector() local timingdata = params.steps:GetTimingData() local lastSecond = params.steps:GetLastSecond() @@ -1237,6 +1466,7 @@ t[#t+1] = Def.ActorFrame { judgeSetting = params.judgeSetting, columns = params.steps:GetNumColumns(), rejudged = params.rejudged, + usingCustomWindows = usingCustomWindows, }) end end diff --git a/Themes/Rebirth/BGAnimations/ScreenEvaluation decorations/scoreBoard.lua b/Themes/Rebirth/BGAnimations/ScreenEvaluation decorations/scoreBoard.lua index 5cf8f0175e..19fb6f72e2 100644 --- a/Themes/Rebirth/BGAnimations/ScreenEvaluation decorations/scoreBoard.lua +++ b/Themes/Rebirth/BGAnimations/ScreenEvaluation decorations/scoreBoard.lua @@ -56,6 +56,23 @@ local actuals = { LeftButtonWidth = ratios.LeftButtonWidth * SCREEN_WIDTH, } +local translations = { + NoReplayData = THEME:GetString("ScreenEvaluation", "NoReplayData"), + You = THEME:GetString("ScreenEvaluation", "You"), + LastScore = THEME:GetString("ScreenEvaluation", "LastScore"), + NoLocalScoresRecorded = THEME:GetString("ScreenEvaluation", "NoLocalScoresRecorded"), + ChartUnranked = THEME:GetString("ScreenEvaluation", "ChartUnranked"), + FetchingScores = THEME:GetString("ScreenEvaluation", "FetchingScores"), + NoOnlineScoresRecorded = THEME:GetString("ScreenEvaluation", "NoOnlineScoresRecorded"), + ShowingXXofXScoresFormatStr = THEME:GetString("ScreenEvaluation", "ShowingXXofXScoresFormatStr"), + Local = THEME:GetString("ScreenEvaluation", "Local"), + Online = THEME:GetString("ScreenEvaluation", "Online"), + AllScores = THEME:GetString("ScreenEvaluation", "AllScores"), + TopScores = THEME:GetString("ScreenEvaluation", "TopScores"), + CurrentRate = THEME:GetString("ScreenEvaluation", "CurrentRate"), + AllRates = THEME:GetString("ScreenEvaluation", "AllRates"), +} + -- we are expecting this file to be loaded with these params precalculated -- in reference, Height is measured divider edge to divider edge -- in reference, Width is the length of the horizontal divider @@ -385,7 +402,7 @@ local function scoreList() if score ~= nil and not score:HasReplayData() then if params.update == "over" then TOOLTIP:Show() - TOOLTIP:SetText("No Replay Data") + TOOLTIP:SetText(translations["NoReplayData"]) elseif params.update == "out" then TOOLTIP:Hide() end @@ -406,7 +423,7 @@ local function scoreList() -- replay data tooltip if score ~= nil and isOver(self) and not score:HasReplayData() then TOOLTIP:Show() - TOOLTIP:SetText("No Replay Data") + TOOLTIP:SetText(translations["NoReplayData"]) elseif score ~= nil and isOver(self) and score:HasReplayData() then TOOLTIP:Hide() end @@ -461,8 +478,12 @@ local function scoreList() local jgGoStr = tostring(score:GetTapNoteScore("TapNoteScore_W4")) local jgBStr = tostring(score:GetTapNoteScore("TapNoteScore_W5")) local jgMiStr = tostring(score:GetTapNoteScore("TapNoteScore_Miss")) + local diff_use = COLORS:getMainColor("SecondaryText") + if score:GetChordCohesion() then + diff_use = COLORS:getColor("evaluation", "ChordCohesionOnScore") + end self:ClearAttributes() - self:diffuse(COLORS:getMainColor("SecondaryText")) + self:diffuse(diff_use) self:diffusealpha(1) self:settextf("%s | %s - %s - %s - %s - %s - %s", wifeStr, jgMaStr, jgPStr, jgGrStr, jgGoStr, jgBStr, jgMiStr) -- could have probably used a loop to do this @@ -490,8 +511,12 @@ local function scoreList() local dstr = string.format("%s %s, %s", m, d, y) local ssr = score:GetSkillsetSSR("Overall") local ssrStr = string.format("%05.2f", ssr) + local diff_use = COLORS:getMainColor("SecondaryText") + if score:GetChordCohesion() then + diff_use = COLORS:getColor("evaluation", "ChordCohesionOnScore") + end self:ClearAttributes() - self:diffuse(COLORS:getMainColor("SecondaryText")) + self:diffuse(diff_use) self:diffusealpha(1) self:settextf("%s | %s", ssrStr, dstr) self:AddAttribute(0, {Length = #ssrStr, Zoom = dateSSRSize, Diffuse = colorByMSD(ssr)}) @@ -511,16 +536,21 @@ local function scoreList() local n = score:GetName() if n == "" then if isLocal then - n = "You" + n = translations["You"] end elseif n == "#P1#" then if score:GetScoreKey() == mostRecentScore:GetScoreKey() then - n = "Last Score" + n = translations["LastScore"] else - n = "You" + n = translations["You"] end end self:settext(n) + if score:GetChordCohesion() then + self:diffuse(COLORS:getColor("evaluation", "ChordCohesionOnScore")) + else + self:diffuse(COLORS:getColor("main", "SecondaryText")) + end end end }, @@ -536,6 +566,11 @@ local function scoreList() if score ~= nil then local rt = score:GetMusicRate() self:settext(getRateString(rt)) + if score:GetChordCohesion() then + self:diffuse(COLORS:getColor("evaluation", "ChordCohesionOnScore")) + else + self:diffuse(COLORS:getColor("main", "SecondaryText")) + end end end } @@ -607,7 +642,7 @@ local function scoreList() if isLocal then if scores ~= nil and #scores == 0 then self:diffusealpha(1) - self:settext("No local scores recorded") + self:settext(translations["NoLocalScoresRecorded"]) else self:diffusealpha(0) self:settext("") @@ -617,13 +652,13 @@ local function scoreList() if scores == nil then self:diffusealpha(1) - self:settext("Chart is unranked") + self:settext(translations["ChartUnranked"]) elseif #scores == 0 and steps and fetchingScores == true then self:diffusealpha(1) - self:settext("Fetching scores...") + self:settext(translations["FetchingScores"]) elseif #scores == 0 and steps and fetchingScores == false then self:diffusealpha(1) - self:settext("No online scores recorded") + self:settext(translations["NoOnlineScoresRecorded"]) else self:diffusealpha(0) self:settext("") @@ -650,7 +685,7 @@ local function scoreList() local lb = clamp((page-1) * (itemCount) + 1, 0, #scores) local ub = clamp(page * itemCount, 0, #scores) - self:settextf("Showing %d-%d of %d scores", lb, ub, #scores) + self:settextf(translations["ShowingXXofXScoresFormatStr"], lb, ub, #scores) end } @@ -680,7 +715,7 @@ t[#t+1] = Def.ActorFrame { txt:valign(0):halign(0) txt:zoom(topButtonSize) txt:maxwidth((actuals.VerticalDividerLeftGap - actuals.LeftButtonLeftGap) / topButtonSize - textZoomFudge) - txt:settext("Local") + txt:settext(translations["Local"]) registerActorToColorConfigElement(txt, "main", "SecondaryText") local bg = self:GetChild("BG") bg:valign(0):halign(0) @@ -717,7 +752,7 @@ t[#t+1] = Def.ActorFrame { txt:valign(0):halign(0) txt:zoom(topButtonSize) txt:maxwidth((actuals.VerticalDividerLeftGap - actuals.LeftButtonLeftGap) / topButtonSize - textZoomFudge) - txt:settext("Online") + txt:settext(translations["Online"]) registerActorToColorConfigElement(txt, "main", "SecondaryText") local bg = self:GetChild("BG") bg:valign(0):halign(0) @@ -768,7 +803,7 @@ t[#t+1] = Def.ActorFrame { txt:valign(0):halign(0) txt:zoom(bottomButtonSize) txt:maxwidth((actuals.VerticalDividerLeftGap - actuals.LeftButtonLeftGap) / bottomButtonSize - textZoomFudge) - txt:settext("All Scores") + txt:settext(translations["AllScores"]) registerActorToColorConfigElement(txt, "main", "SecondaryText") local bg = self:GetChild("BG") bg:valign(0):halign(0) @@ -816,7 +851,7 @@ t[#t+1] = Def.ActorFrame { txt:valign(0):halign(0) txt:zoom(bottomButtonSize) txt:maxwidth((actuals.VerticalDividerLeftGap - actuals.LeftButtonLeftGap) / bottomButtonSize - textZoomFudge) - txt:settext("Top Scores") + txt:settext(translations["TopScores"]) registerActorToColorConfigElement(txt, "main", "SecondaryText") local bg = self:GetChild("BG") bg:valign(0):halign(0) @@ -864,7 +899,7 @@ t[#t+1] = Def.ActorFrame { txt:valign(0):halign(0) txt:zoom(bottomButtonSize) txt:maxwidth((actuals.VerticalDividerLeftGap - actuals.LeftButtonLeftGap) / bottomButtonSize - textZoomFudge) - txt:settext("Current Rate") + txt:settext(translations["CurrentRate"]) registerActorToColorConfigElement(txt, "main", "SecondaryText") local bg = self:GetChild("BG") bg:valign(0):halign(0) @@ -900,7 +935,7 @@ t[#t+1] = Def.ActorFrame { txt:valign(0):halign(0) txt:zoom(bottomButtonSize) txt:maxwidth((actuals.VerticalDividerLeftGap - actuals.LeftButtonLeftGap) / bottomButtonSize - textZoomFudge) - txt:settext("All Rates") + txt:settext(translations["AllRates"]) registerActorToColorConfigElement(txt, "main", "SecondaryText") local bg = self:GetChild("BG") bg:valign(0):halign(0) diff --git a/Themes/Rebirth/BGAnimations/ScreenEvaluation underlay/default.lua b/Themes/Rebirth/BGAnimations/ScreenEvaluation underlay/default.lua index ed81522ece..a8e25d9e26 100644 --- a/Themes/Rebirth/BGAnimations/ScreenEvaluation underlay/default.lua +++ b/Themes/Rebirth/BGAnimations/ScreenEvaluation underlay/default.lua @@ -1,6 +1,7 @@ -- reset context manager as early as possible in the evaluation init process -- this should be a safe place to do it, between all context manager registrations (if they exist) CONTEXTMAN:Reset() +local showbg = function() return PREFSMAN:GetPreference("ShowBackgrounds") end local t = Def.ActorFrame { Name = "UnderlayFile", @@ -19,7 +20,7 @@ t[#t+1] = Def.Sprite { end, SetCommand = function(self, params) self:finishtweening() - if params.song and params.song:GetBackgroundPath() then + if params.song and params.song:GetBackgroundPath() and showbg() then self:visible(true) self:LoadBackground(params.song:GetBackgroundPath()) self:scaletocover(0, 0, SCREEN_WIDTH, SCREEN_BOTTOM) diff --git a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplaycustomization.lua b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplaycustomization.lua index a9de48239f..731c8198ea 100644 --- a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplaycustomization.lua +++ b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplaycustomization.lua @@ -16,6 +16,34 @@ local actuals = { EdgePadding = ratios.EdgePadding * SCREEN_WIDTH, } +local translations = { + CustomizeGameplayInstruction = THEME:GetString("ScreenGameplay", "CustomizeGameplayInstruction"), + Spacing = THEME:GetString("ScreenGameplay", "Spacing"), + Height = THEME:GetString("ScreenGameplay", "Height"), + Width = THEME:GetString("ScreenGameplay", "Width"), + Zoom = THEME:GetString("ScreenGameplay", "Zoom"), + Rotation = THEME:GetString("ScreenGameplay", "Rotation"), + BPMText = THEME:GetString("ScreenGameplay", "BPMText"), + Combo = THEME:GetString("ScreenGameplay", "Combo"), + Cover = THEME:GetString("ScreenGameplay", "Cover"), + DisplayMean = THEME:GetString("ScreenGameplay", "DisplayMean"), + DisplayPercent = THEME:GetString("ScreenGameplay", "DisplayPercent"), + DisplayEWMA = THEME:GetString("ScreenGameplay", "DisplayEWMA"), + DisplayStdDev = THEME:GetString("ScreenGameplay", "DisplayStdDev"), + ErrorBar = THEME:GetString("ScreenGameplay", "ErrorBar"), + FullProgressBar = THEME:GetString("ScreenGameplay", "FullProgressBar"), + JudgeCounter = THEME:GetString("ScreenGameplay", "JudgeCounter"), + Judgment = THEME:GetString("ScreenGameplay", "Judgment"), + LifeP1 = THEME:GetString("ScreenGameplay", "LifeP1"), + MusicRate = THEME:GetString("ScreenGameplay", "MusicRate"), + NoteField = THEME:GetString("ScreenGameplay", "NoteField"), + NPSDisplay = THEME:GetString("ScreenGameplay", "NPSDisplay"), + NPSGraph = THEME:GetString("ScreenGameplay", "NPSGraph"), + PlayerInfo = THEME:GetString("ScreenGameplay", "PlayerInfo"), + Screen = THEME:GetString("ScreenGameplay", "Screen"), + TargetTracker = THEME:GetString("ScreenGameplay", "TargetTracker"), +} + local uiBGAlpha = 0.6 local textButtonHeightFudgeScalarMultiplier = 1.4 local buttonHoverAlpha = 0.6 @@ -284,7 +312,7 @@ local function makeUI() element = elements[index] if element ~= nil then self:diffusealpha(1) - txt:settext(element:GetName()) + txt:settext(translations[element:GetName()] or element:GetName()) bg:zoomto(txt:GetZoomedWidth(), txt:GetZoomedHeight() * textButtonHeightFudgeScalarMultiplier) else self:diffusealpha(0) @@ -344,7 +372,9 @@ local function makeUI() table.sort( elements, function(a, b) - return a:GetName():lower() < b:GetName():lower() + local aname = translations[a:GetName()] or a:GetName() + local bname = translations[b:GetName()] or b:GetName() + return aname:lower() < bname:lower() end ) maxPage = math.ceil(#elements / itemsPerPage) @@ -601,7 +631,7 @@ local function makeUI() self:maxwidth(actuals.MenuWidth / elementNameTextSize) end, UpdateItemInfoCommand = function(self) - self:settextf("%s", selectedElement) + self:settextf("%s", translations[selectedElement] or selectedElement) end, }, LoadFont("Common Normal") .. { @@ -624,8 +654,8 @@ local function makeUI() outstr[#outstr+1] = string.format(fstr, selectedElementCoords["y"]) end if selectedElementCoords["rotation"] ~= nil then - local fstr = selectedElementMovementType == "Rotation" and "[Rotation: %5.2f]" or "Rotation: %5.2f" - outstr[#outstr+1] = string.format(fstr, selectedElementCoords["rotation"]) + local fstr = selectedElementMovementType == "Rotation" and "[%s: %5.2f]" or "%s: %5.2f" + outstr[#outstr+1] = string.format(fstr, translations["Rotation"], selectedElementCoords["rotation"]) end self:settextf(table.concat(outstr, "\n")) end, @@ -644,20 +674,20 @@ local function makeUI() self:y(coordactor:GetY() + coordactor:GetZoomedHeight() + (allowedSpace / itemsPerPage)/2) if selectedElementSizes["zoom"] ~= nil then - local fstr = selectedElementMovementType == "Zoom" and "[Zoom: %5.2f]" or "Zoom: %5.2f" - outstr[#outstr+1] = string.format(fstr, selectedElementSizes["zoom"]) + local fstr = selectedElementMovementType == "Zoom" and "[%s: %5.2f]" or "%s: %5.2f" + outstr[#outstr+1] = string.format(fstr, translations["Zoom"], selectedElementSizes["zoom"]) end if selectedElementSizes["width"] ~= nil then - local fstr = selectedElementMovementType == "Size" and "[Width: %5.2f]" or "Width: %5.2f" - outstr[#outstr+1] = string.format(fstr, selectedElementSizes["width"]) + local fstr = selectedElementMovementType == "Size" and "[%s: %5.2f]" or "%s: %5.2f" + outstr[#outstr+1] = string.format(fstr, translations["Width"], selectedElementSizes["width"]) end if selectedElementSizes["height"] ~= nil then - local fstr = selectedElementMovementType == "Size" and "[Height: %5.2f]" or "Height: %5.2f" - outstr[#outstr+1] = string.format(fstr, selectedElementSizes["height"]) + local fstr = selectedElementMovementType == "Size" and "[%s: %5.2f]" or "%s: %5.2f" + outstr[#outstr+1] = string.format(fstr, translations["Height"], selectedElementSizes["height"]) end if selectedElementSizes["spacing"] ~= nil then - local fstr = selectedElementMovementType == "Spacing" and "[Spacing: %5.2f]" or "Spacing: %5.2f" - outstr[#outstr+1] = string.format(fstr, selectedElementSizes["spacing"]) + local fstr = selectedElementMovementType == "Spacing" and "[%s: %5.2f]" or "%s: %5.2f" + outstr[#outstr+1] = string.format(fstr, translations["Spacing"], selectedElementSizes["spacing"]) end self:settextf(table.concat(outstr, "\n")) end @@ -670,7 +700,7 @@ local function makeUI() self:addy(actuals.MenuHeight - actuals.EdgePadding) self:zoom(uiInstructionTextSize) self:maxwidth(actuals.MenuWidth / uiInstructionTextSize) - self:settext("Space to scroll movement types") + self:settext(translations["CustomizeGameplayInstruction"]) end, } } diff --git a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplayelements.lua b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplayelements.lua index 264ef640a1..1aa3ed4007 100644 --- a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplayelements.lua +++ b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplayelements.lua @@ -119,10 +119,22 @@ if playerConfig:get_data().BPMDisplay then t[#t+1] = LoadActor("bpmdisplay") end +if playerConfig:get_data().DisplayEWMA then + t[#t+1] = LoadActor("displayewma") +end + +if playerConfig:get_data().DisplayMean then + t[#t+1] = LoadActor("displaymean") +end + if playerConfig:get_data().DisplayPercent then t[#t+1] = LoadActor("displaypercent") end +if playerConfig:get_data().DisplayStdDev then + t[#t+1] = LoadActor("displaystddev") +end + if playerConfig:get_data().ErrorBar ~= 0 then t[#t+1] = LoadActor("errorbar") end @@ -138,14 +150,10 @@ end -- lane cover is in Graphics/NoteField cover.lua if (NSMAN:IsETTP() and Var("LoadingScreen"):find("Net") ~= nil) or -(playerConfig:get_data().leaderboardEnabled and DLMAN:IsLoggedIn()) then +(playerConfig:get_data().Leaderboard == 1 and DLMAN:IsLoggedIn()) or (playerConfig:get_data().Leaderboard == 2) then t[#t+1] = LoadActor("leaderboard") end -if playerConfig:get_data().DisplayMean then - t[#t+1] = LoadActor("meandisplay") -end - if playerConfig:get_data().MeasureCounter then t[#t+1] = LoadActor("measurecounter") end diff --git a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplaypractice.lua b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplaypractice.lua index a5a2e13463..425497a9c5 100644 --- a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplaypractice.lua +++ b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplaypractice.lua @@ -159,8 +159,10 @@ t[#t + 1] = LoadActorWithParams("../../chorddensitygraph.lua", {sizing = { NPSThickness = 1.5, TextSize = 0.45, }}) .. { - Name = "PracticeCDGraph", BeginCommand = function(self) + -- properly rename this actor to overrite the default name coming from chorddensitygraph.lua + self:name("PracticeCDGraph") + self:playcommand("SetUpMovableValues") self:playcommand("LoadDensityGraph", {steps = GAMESTATE:GetCurrentSteps(), song = GAMESTATE:GetCurrentSong()}) -- doing this in a really awkward way to inject the desired behavior into the existing SeekBar @@ -203,8 +205,6 @@ t[#t+1] = Def.Quad { Name = "BookmarkPos", InitCommand = function(self) -- trickery - self:SetFakeParent(self:GetParent():GetChild("PracticeCDGraph")) - self:valign(0) self:zoomto(bookmarkWidth, height) self:diffuse(bookmarkColor) @@ -212,6 +212,10 @@ t[#t+1] = Def.Quad { self:draworder(1100) self:visible(false) end, + FirstUpdateCommand = function(self) + -- have to call this late because the graph is named late (in BeginCommand) + self:SetFakeParent(self:GetParent():GetChild("PracticeCDGraph")) + end, SetCommand = function(self) self:visible(true) self:zoomto(bookmarkWidth, height) diff --git a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplayreplay.lua b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplayreplay.lua index 5719daafa1..6962d9daac 100644 --- a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplayreplay.lua +++ b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/_gameplayreplay.lua @@ -111,13 +111,14 @@ local width = 60 local height = 30 local uiBGAlpha = 0.6 -local translated_info = { +local translations = { Pause = THEME:GetString("ScreenGameplay", "ButtonPause"), FastForward = THEME:GetString("ScreenGameplay", "ButtonFastForward"), Rewind = THEME:GetString("ScreenGameplay", "ButtonRewind"), Play = THEME:GetString("ScreenGameplay", "ButtonPlay"), - Results = "Results", - Exit = "Exit", + Results = THEME:GetString("ScreenGameplay", "Results"), + Exit = THEME:GetString("ScreenGameplay", "Exit"), + MustBePaused = THEME:GetString("ScreenGameplay", "MustBePaused"), } local function button(i, txt, click, mustBePaused) @@ -148,7 +149,7 @@ local function button(i, txt, click, mustBePaused) self:diffusealpha(hoverAlpha) if mustBePaused then if not GAMESTATE:IsPaused() then - TOOLTIP:SetText("Must be paused") + TOOLTIP:SetText(translations["MustBePaused"]) TOOLTIP:Show() end end @@ -208,35 +209,35 @@ scroller[#scroller + 1] = Def.ActorFrame { }, button(1, - translated_info["Pause"], + translations["Pause"], function(self) SCREENMAN:GetTopScreen():TogglePause() local paused = GAMESTATE:IsPaused() - self:GetParent():GetChild("Text"):settext(paused and translated_info["Play"] or translated_info["Pause"]) + self:GetParent():GetChild("Text"):settext(paused and translations["Play"] or translations["Pause"]) end ), button(2, - translated_info["FastForward"], + translations["FastForward"], function(self) SCREENMAN:GetTopScreen():SetSongPosition(SCREENMAN:GetTopScreen():GetSongPosition() + 5) end, true ), button(3, - translated_info["Rewind"], + translations["Rewind"], function(self) SCREENMAN:GetTopScreen():SetSongPosition(SCREENMAN:GetTopScreen():GetSongPosition() - 5) end, true ), button(4, - translated_info["Results"], + translations["Results"], function(self) SCREENMAN:GetTopScreen():PostScreenMessage("SM_NotesEnded", 0) end ), button(5, - translated_info["Exit"], + translations["Exit"], function(self) SCREENMAN:GetTopScreen():Cancel() end diff --git a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/displayewma.lua b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/displayewma.lua new file mode 100644 index 0000000000..1d56556b55 --- /dev/null +++ b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/displayewma.lua @@ -0,0 +1,73 @@ +-- the exponential weighted moving average display. it displays the ewma as a number instead of like the error bar + +local formatstr = THEME:GetString("ScreenGameplay", "EWMADisplayFormatStr") +local EWMATextSize = GAMEPLAY:getItemHeight("ewmaDisplayText") +local bgMargin = 4 +local bgalpha = 0.4 + +local alph = 0.07 -- not opacity, math for ewma +local avg = 0 +local lastavg = 0 + +return Def.ActorFrame { + Name = "DisplayEWMA", + InitCommand = function(self) + self:playcommand("SetUpMovableValues") + registerActorToCustomizeGameplayUI({ + actor = self, + coordInc = {5,1}, + zoomInc = {0.1,0.05}, + }) + end, + SetUpMovableValuesMessageCommand = function(self) + self:xy(MovableValues.DisplayEWMAX, MovableValues.DisplayEWMAY) + self:zoom(MovableValues.DisplayEWMAZoom) + end, + JudgmentMessageCommand = function(self, params) + -- should work fine only for judged taps, not misses or holds + if not params.HoldNoteScore and params.Offset ~= nil and params.Offset < 1000 then + avg = alph * params.Offset + (1 - alph) * lastavg + lastavg = avg + self:playcommand("UpdateEWMAText") + end + end, + PracticeModeResetMessageCommand = function(self) + avg = 0 + lastavg = 0 + self:playcommand("UpdateEWMAText") + end, + UpdateEWMATextCommand = function(self) + local bg = self:GetChild("EWMABacking") + local perc = self:GetChild("DisplayEWMA") + + if perc then + if avg == 0 then + perc:settextf(formatstr, 0) + else + perc:settextf(formatstr, avg) + end + end + if bg and perc then + bg:zoomto(perc:GetZoomedWidth() + bgMargin, perc:GetZoomedHeight() + bgMargin) + end + end, + + Def.Quad { + Name = "EWMABacking", + InitCommand = function(self) + self:halign(1):valign(0) + self:xy(bgMargin/2, -bgMargin/2) + registerActorToColorConfigElement(self, "gameplay", "PrimaryBackground") + self:diffusealpha(bgalpha) + end + }, + LoadFont("Common Large") .. { + Name = "DisplayEWMA", + InitCommand = function(self) + self:halign(1):valign(0) + self:zoom(EWMATextSize) + registerActorToColorConfigElement(self, "gameplay", "PrimaryText") + self:diffusealpha(1) + end, + } +} \ No newline at end of file diff --git a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/meandisplay.lua b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/displaymean.lua similarity index 96% rename from Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/meandisplay.lua rename to Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/displaymean.lua index 51b0f94b59..72ab46fd55 100644 --- a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/meandisplay.lua +++ b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/displaymean.lua @@ -1,7 +1,7 @@ -- the mean display. it displays the mean -- i dunno less copy paste whatever bro -local formatstr = "%5.2fms" +local formatstr = THEME:GetString("ScreenGameplay", "MeanDisplayFormatStr") local meanTextSize = GAMEPLAY:getItemHeight("meanDisplayText") local bgMargin = 4 local bgalpha = 0.4 diff --git a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/displaystddev.lua b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/displaystddev.lua new file mode 100644 index 0000000000..f9035d65a6 --- /dev/null +++ b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/displaystddev.lua @@ -0,0 +1,80 @@ +-- the standard deviation display. it displays the standard deviation. + +local formatstr = THEME:GetString("ScreenGameplay", "StdDevDisplayFormatStr") +local stddevTextSize = GAMEPLAY:getItemHeight("stddevDisplayText") +local bgMargin = 4 +local bgalpha = 0.4 + +-- this is welfords online algorithm for variance (we can get sd from variance) +-- it might not be necessary here, didnt really put a lot of thought into it +-- but its the same thing that is used for ReplaySnapshots +local runningmean = 0 +local runningvariance = 0 +local tapcount = 0 + +return Def.ActorFrame { + Name = "DisplayStdDev", + InitCommand = function(self) + self:playcommand("SetUpMovableValues") + registerActorToCustomizeGameplayUI({ + actor = self, + coordInc = {5,1}, + zoomInc = {0.1,0.05}, + }) + end, + SetUpMovableValuesMessageCommand = function(self) + self:xy(MovableValues.DisplayStdDevX, MovableValues.DisplayStdDevY) + self:zoom(MovableValues.DisplayStdDevZoom) + end, + JudgmentMessageCommand = function(self, params) + -- should work fine only for judged taps, not misses or holds + if not params.HoldNoteScore and params.Offset ~= nil and params.Offset < 1000 then + tapcount = tapcount + 1 + local delta = params.Offset - runningmean + runningmean = runningmean + (delta / tapcount) + local delta2 = params.Offset - runningmean + runningvariance = runningvariance + (delta * delta2) + self:playcommand("UpdateStdDevText") + end + end, + PracticeModeResetMessageCommand = function(self) + tapcount = 0 + runningmean = 0 + runningvariance = 0 + self:playcommand("UpdateStdDevText") + end, + UpdateStdDevTextCommand = function(self) + local bg = self:GetChild("StdDevBacking") + local perc = self:GetChild("DisplayStdDev") + + if perc then + if tapcount == 0 or tapcount == 1 then + perc:settextf(formatstr, 0) + else + perc:settextf(formatstr, math.sqrt(runningvariance / (tapcount - 1))) + end + end + if bg and perc then + bg:zoomto(perc:GetZoomedWidth() + bgMargin, perc:GetZoomedHeight() + bgMargin) + end + end, + + Def.Quad { + Name = "StdDevBacking", + InitCommand = function(self) + self:halign(1):valign(0) + self:xy(bgMargin/2, -bgMargin/2) + registerActorToColorConfigElement(self, "gameplay", "PrimaryBackground") + self:diffusealpha(bgalpha) + end + }, + LoadFont("Common Large") .. { + Name = "DisplayStdDev", + InitCommand = function(self) + self:halign(1):valign(0) + self:zoom(stddevTextSize) + registerActorToColorConfigElement(self, "gameplay", "PrimaryText") + self:diffusealpha(1) + end, + } +} \ No newline at end of file diff --git a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/errorbar.lua b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/errorbar.lua index af1188a37b..1982b17dd1 100644 --- a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/errorbar.lua +++ b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/errorbar.lua @@ -27,9 +27,9 @@ local earlylateTextSize = GAMEPLAY:getItemHeight("errorBarText") -- EWMA loads 1 bar and places it according to the EWMA of the previous n taps local errorbarType = playerConfig:get_data().ErrorBar == 1 and "Regular" or "EWMA" -local translated_info = { - ErrorLate = "Late", - ErrorEarly = "Early", +local translations = { + ErrorLate = THEME:GetString("ScreenGameplay", "ErrorBarLate"), + ErrorEarly = THEME:GetString("ScreenGameplay", "ErrorBarEarly"), } -- procedurally generated error bars @@ -122,7 +122,7 @@ local t = Def.ActorFrame { self:zoom(earlylateTextSize) end, BeginCommand = function(self) - self:settext(translated_info["ErrorLate"]) + self:settext(translations["ErrorLate"]) self:diffusealpha(0):smooth(0.5):diffusealpha(0.5):sleep(1.5):smooth(0.5):diffusealpha(0) end, SetUpMovableValuesMessageCommand = function(self) @@ -135,7 +135,7 @@ local t = Def.ActorFrame { self:zoom(earlylateTextSize) end, BeginCommand = function(self) - self:settext(translated_info["ErrorEarly"]) + self:settext(translations["ErrorEarly"]) self:diffusealpha(0):smooth(0.5):diffusealpha(0.5):sleep(1.5):smooth(0.5):diffusealpha(0):queuecommand("Doot") end, SetUpMovableValuesMessageCommand = function(self) diff --git a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/fullprogressbar.lua b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/fullprogressbar.lua index 4d80154d46..87761271e3 100644 --- a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/fullprogressbar.lua +++ b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/fullprogressbar.lua @@ -5,6 +5,10 @@ local height = SCREEN_HEIGHT / 50 local alpha = 0.7 local isReplay = GAMESTATE:GetPlayerState():GetPlayerController() == "PlayerController_Replay" and not allowedCustomization +local translations = { + MustBePaused = THEME:GetString("ScreenGameplay", "MustBePaused"), +} + local progressbarTextSize = GAMEPLAY:getItemHeight("fullProgressBarText") local function bounds() @@ -26,7 +30,7 @@ local replaySlider = isReplay and if params.event ~= "DeviceButton_left mouse button" then return end if not GAMESTATE:IsPaused() then - TOOLTIP:SetText("Music must be paused") + TOOLTIP:SetText(translations["MustBePaused"]) TOOLTIP:Show() end diff --git a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/leaderboard.lua b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/leaderboard.lua index 8b4e5c0f3b..1b430a6e9e 100644 --- a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/leaderboard.lua +++ b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/leaderboard.lua @@ -1,14 +1,16 @@ local leaderboardEnabled = (NSMAN:IsETTP() and SCREENMAN:GetTopScreen() and SCREENMAN:GetTopScreen():GetName() == "ScreenNetStageInformation") or - (playerConfig:get_data().leaderboardEnabled and DLMAN:IsLoggedIn()) + ((playerConfig:get_data().Leaderboard or 0) ~= 0 and DLMAN:IsLoggedIn()) if not leaderboardEnabled then return Def.ActorFrame {} end local isMulti = NSMAN:IsETTP() and SCREENMAN:GetTopScreen() and SCREENMAN:GetTopScreen():GetName():find("Net") ~= nil or false +local leaderboardIsLocal = not isMulti and (playerConfig:get_data().Leaderboard or 0) == 2 --- bad idea +local toggledRateFilter = false if not DLMAN:GetCurrentRateFilter() then DLMAN:ToggleRateFilter() + toggledRateFilter = true end local jdgs = { @@ -77,6 +79,12 @@ local t = Def.ActorFrame { spacingInc = {5,1}, }) end, + EndCommand = function(self) + if toggledRateFilter then + -- undo the toggle from above + DLMAN:ToggleRateFilter() + end + end, OnCommand = function(self) self:playcommand("SetUpMovableValues") for i, entry in ipairs(entryActors) do @@ -135,12 +143,34 @@ local function scoreUsingMultiScore(idx) end local function setUpOnlineScores() - if isMulti then + if leaderboardIsLocal then + onlineScores = {} + -- get your own scores + local localrtTable = getRateTable() + if localrtTable ~= nil then + -- only display if scores on this rate are found + local found = false + local eps = 0.01 + localrates, localrateIndex = getUsedRates(localrtTable) + for i,r in ipairs(localrates) do + local raten = tonumber(r:gsub("x", ""), 10) + if math.abs(raten - getCurRateValue()) < eps then + localrateIndex = i + found = true + end + end + if found then + onlineScores = localrtTable[localrates[localrateIndex]] + end + end + elseif isMulti then + -- get scores from multi multiScores = NSMAN:GetMPLeaderboard() for i = 1, NUM_ENTRIES do onlineScores[i] = scoreUsingMultiScore(i) end else + -- get scores from chart leaderboards onlineScores = DLMAN:GetChartLeaderBoard(GAMESTATE:GetCurrentSteps():GetChartKey()) or {} end diff --git a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/npsdisplay.lua b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/npsdisplay.lua index 94a4914e96..d15780df41 100644 --- a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/npsdisplay.lua +++ b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/npsdisplay.lua @@ -34,9 +34,9 @@ local lastJudgment = "TapNoteScore_None" local noteSum = 0 local peakNPS = 0 -local translated_info = { - Peak = "Peak", - NPS = "NPS", +local translations = { + Peak = THEME:GetString("ScreenGameplay", "NPSDisplayPeak"), + NPS = THEME:GetString("ScreenGameplay", "NPSDisplayNPS"), } --------------- @@ -105,7 +105,7 @@ local function Update(self) -- every time this function is called. -- We don't display the decimal values due to lack of precision from having a relatively small time window. if enabledNPSDisplay then - self:GetChild("NPSDisplay"):GetChild("Text"):settextf("%0.0f %s (%s %0.0f)", curNPS, translated_info["NPS"], translated_info["Peak"], peakNPS) + self:GetChild("NPSDisplay"):GetChild("Text"):settextf("%0.0f %s (%s %0.0f)", curNPS, translations["NPS"], translations["Peak"], peakNPS) end end end diff --git a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/playerinfo.lua b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/playerinfo.lua index 1eabfe7c04..c9042fc208 100644 --- a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/playerinfo.lua +++ b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/elements/playerinfo.lua @@ -1,7 +1,7 @@ -- Various player and stage info -local translated_info = { - Judge = "Judge", - Scoring = "Scoring", +local translations = { + Judge = THEME:GetString("ScreenGameplay", "JudgeDifficulty"), + Scoring = THEME:GetString("ScreenGameplay", "ScoringType"), } local modstringTextSize = GAMEPLAY:getItemHeight("playerInfoModsText") @@ -133,7 +133,7 @@ return Def.ActorFrame { end, BeginCommand = function(self) self:xy(avatarSize + bufferspace, avatarSize/24) - self:settextf("%s: %d", translated_info["Judge"], GetTimingDifficulty()) + self:settextf("%s: %d", translations["Judge"], GetTimingDifficulty()) end }, LoadFont("Common Normal") .. { @@ -146,7 +146,7 @@ return Def.ActorFrame { end, BeginCommand = function(self) self:xy(avatarSize + bufferspace, avatarSize/2 - avatarSize/8) - self:settextf("%s: %s", translated_info["Scoring"], "Wife") + self:settextf("%s: %s", translations["Scoring"], "Wife") end }, } diff --git a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/titlesplash.lua b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/titlesplash.lua index 1f587db910..64429e6961 100644 --- a/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/titlesplash.lua +++ b/Themes/Rebirth/BGAnimations/ScreenGameplay overlay/titlesplash.lua @@ -1,12 +1,14 @@ local mods = {} -local translated_info = { - InvalidMods = THEME:GetString("ScreenGameplay", "InvalidMods") +local translations = { + InvalidMods = THEME:GetString("ScreenGameplay", "InvalidMods"), + By = THEME:GetString("ScreenGameplay", "CreatedBy"), } local textSize = 0.8 local subtextSize = 0.75 local bigTextSize = 1.2 +local authorSize = 0.60 local width = SCREEN_WIDTH / 3 local linesize = 75 / 1080 * SCREEN_HEIGHT @@ -78,7 +80,7 @@ local t = Def.ActorFrame { LoadFont("Common Normal") .. { Name = "DestroyMe4", InitCommand = function(self) - self:xy(SCREEN_CENTER_X, SCREEN_CENTER_Y - linesize) + self:xy(SCREEN_CENTER_X, SCREEN_CENTER_Y - linesize * 1.2) self:zoom(subtextSize) self:diffuse(getGameplayColor("SplashText")) self:diffusealpha(0) @@ -104,6 +106,27 @@ local t = Def.ActorFrame { self:GetParent():queuecommand("Doot") end }, + LoadFont("Common Normal") .. { + Name = "DestroyMe6", + InitCommand = function(self) + self:xy(SCREEN_CENTER_X, SCREEN_CENTER_Y - linesize * 0.9) + self:zoom(authorSize) + self:diffuse(getGameplayColor("SplashText")) + self:diffusealpha(0) + self:maxwidth(width / subtextSize) + end, + BeginCommand = function(self) + local auth = GAMESTATE:GetCurrentSong():GetOrTryAtLeastToGetSimfileAuthor() + self:settextf("%s: %s", translations["By"], auth) + end, + OnCommand = function(self) + self:smooth(0.5) + self:diffusealpha(1) + self:sleep(1) + self:smooth(0.7) + self:diffusealpha(0) + end + }, LoadFont("Common Normal") .. { Name = "DestroyMe5", InitCommand = function(self) @@ -120,7 +143,7 @@ local t = Def.ActorFrame { for _,mod in ipairs(mods) do table.insert(translated, THEME:HasString("OptionNames", mod) and THEME:GetString("OptionNames", mod) or mod) end - self:settextf("%s\n%s", translated_info["InvalidMods"], table.concat(translated, "\n")) + self:settextf("%s\n%s", translations["InvalidMods"], table.concat(translated, "\n")) end end, OnCommand = function(self) diff --git a/Themes/Rebirth/BGAnimations/ScreenGameplay underlay.lua b/Themes/Rebirth/BGAnimations/ScreenGameplay underlay.lua index 89cb1a0bac..3704fa1272 100644 --- a/Themes/Rebirth/BGAnimations/ScreenGameplay underlay.lua +++ b/Themes/Rebirth/BGAnimations/ScreenGameplay underlay.lua @@ -8,14 +8,8 @@ CONTEXTMAN:Reset() -- also permamirror and receptorsize/mini because this is early in gameplay init again local modslevel = "ModsLevel_Preferred" local playeroptions = GAMESTATE:GetPlayerState():GetPlayerOptions(modslevel) -local profile = PROFILEMAN:GetProfile(PLAYER_1) local replaystate = GAMESTATE:GetPlayerState():GetPlayerController() == "PlayerController_Replay" --- turn on mirror if song is flagged as perma mirror -if profile:IsCurrentChartPermamirror() and not replaystate then - playeroptions:Mirror(true) -end - -- dont apply the player defined receptor size mini if viewing an emulated replay local emulating = PREFSMAN:GetPreference("ReplaysUseScoreMods") and replaystate if not emulating then @@ -33,19 +27,4 @@ else songoptions:RandomBGOnly(false) end -local showbgs = themeConfig:get_data().global.ShowBackgrounds -if not showbgs then - return Def.ActorFrame { - Def.Quad { - Name = "SCUFFEDBACKGROUND", - InitCommand = function(self) - self:valign(0):halign(0) - self:zoomto(SCREEN_WIDTH, SCREEN_HEIGHT) - self:diffuse(color("#000000")) - self:diffusealpha(1) - end, - }, - } -end - return Def.ActorFrame {} \ No newline at end of file diff --git a/Themes/Rebirth/BGAnimations/ScreenHelpMenu overlay/helpDisplay.lua b/Themes/Rebirth/BGAnimations/ScreenHelpMenu overlay/helpDisplay.lua index b10608d25b..7b4281c2ee 100644 --- a/Themes/Rebirth/BGAnimations/ScreenHelpMenu overlay/helpDisplay.lua +++ b/Themes/Rebirth/BGAnimations/ScreenHelpMenu overlay/helpDisplay.lua @@ -47,6 +47,12 @@ local actuals = { IconExitHeight = ratios.IconExitHeight * SCREEN_HEIGHT, } +local translations = { + Title = THEME:GetString("ScreenHelpMenu", "Title"), + Exit = THEME:GetString("ScreenHelpMenu", "Exit"), + Instruction = THEME:GetString("ScreenHelpMenu", "Instruction"), +} + local infoTextSize = 0.65 local listTextSize = 0.4 local titleTextSize = 0.95 @@ -88,6 +94,12 @@ local function helpMenu() ShortDescription = "1 sentence", -- this appears as a subtext to the large text in the main area Description = "a paragraph", -- this appears as regular text in the remaining area Image = "path to an image", -- OPTIONAL -- if supplied, this takes up the right half of the main area + -- NOTE::: + -- Alternative way to construct this data: + -- missing required fields will be filled in with GetString("ScreenHelpMenu", "item name") + Name = "optionname", + ShortDescription = THEME:GetString("ScreenHelpMenu", "optionnameshortdescription") + Description = THEME:GetString("ScreenHelpMenu", "optionnamedescription") }, [2] = {}, .... } @@ -95,414 +107,240 @@ local function helpMenu() local optionDefs = { ["Common Pattern Terminology"] = { { - Name = "Roll (1234)", - ShortDescription = "Vaguely a jumptrill", - Description = "Roll is the common name given to this type of pattern which requires you to press all columns in succession before repeating any columns again. It comes in several forms.\n\nThe specific roll depicted here may be referred to as an ascending roll. If it went in the opposite direction (4321) it would be descending.\n\nThe direction of the roll does not affect its capacity to be jumptrilled. Only the speed of the roll does.", + Name = "RollAscending", Image = THEME:GetPathG("", "Patterns/1234 roll"), }, { - Name = "Roll (1243)", - ShortDescription = "Vaguely a jumptrill", - Description = "Roll is the common name given to this type of pattern which requires you to press all columns in succession before repeating any columns again. It comes in several forms.\n\nThe specific roll depicted here may be referred to as a split roll. If the pattern began with the opposite hand (4312) it would be functionally equivalent.\n\nRegardless, this roll variant can be effectively jumptrilled if its speed is sufficient.", + Name = "RollInward", Image = THEME:GetPathG("", "Patterns/1243 roll"), }, { - Name = "Roll (4132)", - ShortDescription = "Vaguely a split jumptrill", - Description = "Roll is the common name given to this type of pattern which requires you to press all columns in succession before repeating any columns again. It comes in several forms.\n\nThe specific roll depicted here may be referred to as a split roll, split hand roll, or split trill. It may also begin in reverse order (3241, inside out) but still remains functionally equivalent.\n\nThis roll variant is more difficult to jumptrill than others. When hit quickly, it is physically similar to a split jumptrill.", + Name = "RollSplit", Image = THEME:GetPathG("", "Patterns/1423 roll"), }, { Name = "Gluts", - ShortDescription = "Another word for 'in excess'", - Description = "Gluts is a broad term which captures jumpgluts and handgluts. It's frequently debated what defines a glut or even if a handglut exists.\n\nThe most accepted definition of a glut is literal: jumpgluts are many continuous jumps (jumpjacks) which typically form minijacks as they change column pairs over the course of the glut run. Depicted in the image is a run of jumpjacks referred to as gluts because of the minijacks on column 1 and 4.\n\nGluts are a subset of chordjacks with more focus on jack speed than chords.", Image = THEME:GetPathG("", "Patterns/gluts"), }, { Name = "Chordjack", - ShortDescription = "Chords which form jacks", - Description = "Chordjack is the blanket term for patterns made up entirely of n-chords which form jacks.\n\nThe chords contained in the overall pattern do not have to be the same. Jumps, hands, or quads are valid. Depicted to the right is a very generic medium density chordjack pattern containing only jumps and hands.", Image = THEME:GetPathG("", "Patterns/chordjacks"), }, { - Name = "Dense Chordjack", - ShortDescription = "Don't break your keyboard", - Description = "Dense chordjacks are a specialization of chordjacks which are biased toward hands and quads. At high enough density, this may be referred to as holedodge because when reading, there are more notes than empty spaces.\n\nDense chordjacks require a lot of stamina and tend to have embedded longjacks due to the pattern being almost entirely hands and quads.", + Name = "DenseChordjack", Image = THEME:GetPathG("", "Patterns/dense chordjack"), }, { Name = "Stream", - ShortDescription = "Continuous single taps", - Description = "Just like the name implies, a stream is a continuous stream of notes. More specifically, these continuous notes are mostly on separate columns, not forming jacks. There can be any kind of variation to the patterning as long as it doesn't deviate too much from the pure definition.\n\nMinijacks, chords, or other patterns that can be embedded may be found within a stream, but only serve to make it more difficult unless they dominate the overall pattern.\n\nTo the right is a stream which is slightly rolly.", Image = THEME:GetPathG("", "Patterns/streams"), }, { Name = "Jumpstream", - ShortDescription = "Stream with jumps", - Description = "Jumpstream expands the definition of a stream by requiring jumps at a certain frequency within the pattern. Other than that, it is still a stream.\n\nDepicted to the right is a simple jumpstream pattern with an anchor on column 1. A more observant player may also recognize that this pattern in isolation can be jumptrilled.", Image = THEME:GetPathG("", "Patterns/jumpstream"), }, { Name = "Handstream", - ShortDescription = "Stream with hands", - Description = "Handstream expands the definition of a stream by requiring hands at a certain frequency within the pattern. It is also not uncommon to find jumps embedded within a handstream. This may be referred to as dense handstream, although the most dense handstream is purely hands and single taps.\n\nAnchors are more common in a handstream since the charter only has 4 ways to fit a hand into 4 columns. In the depiction to the right, there is an anchor on column 4 and, depending who you ask, also column 3.", Image = THEME:GetPathG("", "Patterns/handstream"), }, { Name = "Quadstream", - ShortDescription = "Stream with quads", - Description = "Quadstream takes the definition of stream so far that it begins to look like chordjacks.\n\nIt forms a minijack with a quad using a single tap (usually) and still flows like a stream as opposed to pure chordjacks.\n\nIncreasing the density of quads will lose this characteristic due to the limited column space.", Image = THEME:GetPathG("", "Patterns/quadstream"), }, { Name = "Trill", - ShortDescription = "Like musical theory", - Description = "A trill is a sequence of two continuously alternating notes. In the context of this game, they can be either on one hand or split between both hands.\n\nWhen a trill is one handed, it is called a one hand trill. Otherwise, it is a two hand trill. Trills are not restricted to two adjacent columns, and can be on columns 1 and 3 for example.\n\nDepicted to the right is a simple two hand trill.", Image = THEME:GetPathG("", "Patterns/trill"), }, { Name = "Jumptrill", - ShortDescription = "Can be played blind", - Description = "Jumptrill is a very simple expansion of a two hand trill. Jump on one hand and then jump on the other. Most often this pattern makes up the highest NPS section of a chart unless it is dense chordjacks.\n\nOne special thing about the ordinary jumptrill is that many other patterns can be broken down into a jumptrill, which allows cheese-oriented gameplay. We don't recommend doing this too frequently for the sake of your scores and habit forming.", Image = THEME:GetPathG("", "Patterns/jumptrill"), }, { - Name = "Split Jumptrill [13][24]", - ShortDescription = "Jumptrill but dangerous", - Description = "Split jumptrill is a shuffled jumptrill. It forms two one hand trills instead of one pure jumptrill.\n\nSplit jumptrills are very annoying due to many players' inability to hit them fluently. This specific variant of split jumptrills can be more difficult than the other variant of split jumptrills because a player tends to be more inclined to jumptrill or roll when simultaneously doing a same-direction rolling motion with both hands. Luckily they can be jumptrilled if hit just right.\n\nTo the right is a long split jumptrill.", + Name = "SplitJumptrill", Image = THEME:GetPathG("", "Patterns/13 split jt"), }, { - Name = "Split Jumptrill [14][23]", - ShortDescription = "Jumptrill but dangerous", - Description = "Split jumptrill is a shuffled jumptrill. It forms two one hand trills instead of one pure jumptrill.\n\nSplit jumptrills are very annoying due to many players' inability to hit them fluently. Compared to the other variant of split jumptrills, this one is usually easier because it can feel more natural. Anyways, they can be jumptrilled if hit just right.\n\nTo the right is a long split jumptrill.", + Name = "SplitJumptrillTrainTrack", Image = THEME:GetPathG("", "Patterns/14 split jt"), }, { Name = "Minijacks", - ShortDescription = "Instant combo breaker", - Description = "Minijacks are pairs of jacks. They can be continuous like the image to the right or embedded in some other pattern like a stream.\nMinijacks can be difficult to hit accurately as they get closer together because of the nature of the hit window. Imagine hitting one note within 180ms. Now hit two notes in that same window. If the minijack is fast enough or the player is slow enough, it's guaranteed points lost.\nMinijacks can be embedded within broader jack oriented patterns as a jack burst. Most commonly they are in isolation or in stream transitions that jack instead of trill.", Image = THEME:GetPathG("", "Patterns/minijacks"), }, { Name = "Longjack", - ShortDescription = "Continuous taps", - Description = "A jack, or jackhammer, is a set of continuous taps in the same column. A longjack is the same thing, but a little longer than usual.\n\nThe length of a jack that is considered a longjack is debated, but generally it is around 5-6 notes. The longjack can continue into infinity.\n\nLongjacks are the base pattern which make up continuous jumpjacks, handjacks, or quadjacks. This base pattern also makes up much of the structure for files oriented towards the vibro playstyle.", Image = THEME:GetPathG("", "Patterns/longjack"), }, { Name = "Anchor", - ShortDescription = "Basically embedded longjacks", - Description = "An anchor is a common continuous set of columns being utilized relative to the other columns contained in a pattern. Most commonly, anchors are only one column at a time.\n\nAn anchor may be on a snap alternating from the rest of the pattern or not, or a bit of both. Anchors that last a while break down to be longjacks, which will cause an overall pattern to be more stamina draining.\n\nThe image to the right depicts an anchor on column 4.", Image = THEME:GetPathG("", "Patterns/anchor"), }, { Name = "Minedodge", - ShortDescription = "Spicy notes", - Description = "Minedodge is the term for a type of chart or general pattern which contains notes that are intentionally placed near mines to increase difficulty.\n\nMinedodge does not actually change the MSD of a chart, because the calculator measures physical difficulty of the taps.\n\nThe difficulty of minedodge comes from the necessity of more precisely timing the press and release of notes and increased difficulty to read the notes depending on the noteskin used.", Image = THEME:GetPathG("", "Patterns/minedodge"), }, { Name = "Hold", - ShortDescription = "Don't let go", - Description = "Holds are a note type which require the player to hold the button for the entire duration of the note. They may also be referred to as freezes or long notes.\n\nPatterns made up of more holds are sometimes referred to as a holdstream or, at the extreme end of the spectrum, full inverse (all empty space is a hold).\n\nIn this game, a hold can be released for a short period of time dependent on the judge difficulty. On judge 4, the time is 250ms. Holds can then be regrabbed. Holds do not have release timing, but release timing can be emulated with a lift or mine.", Image = THEME:GetPathG("", "Patterns/hold"), }, { - Name = "Roll / Rolld", - ShortDescription = "Keep tapping", - Description = "Roll note types, not to be confused with the roll pattern, are a hold type which require the player to continuously tap the button for the duration of the note. They may also be referred to as a rolld.\n\nRolls cannot be held and must be continuously tapped. The speed of the tap has a threshold the player receives no judgment for, but it gets smaller at higher judge difficulties. On judge 4, the player has up to 500ms between taps.", + Name = "Rolld", Image = THEME:GetPathG("", "Patterns/rolld"), }, { Name = "Burst", - ShortDescription = "Explosive speed", - Description = "A burst is a pattern specialization which means exactly what it says. Relative to its pattern context, a burst is much quicker.\n\nBursts can come in any form which matches that definition, not only the scenario depicted to the right. Jacks and jumpstream can also burst. The point is that it is a quicker collection of notes, almost like a compressed pattern.\n\nOften, a burst is patterned in such a way that it isn't difficult to full combo. But that isn't always the case!", Image = THEME:GetPathG("", "Patterns/burst"), }, { Name = "Polyrhythm", - ShortDescription = "Brain melting patterns", - Description = "Polyrhythms are a pattern specialization which indicates that multiple rhythms are being charted simultaneously, leading to alternating snaps being utilized. Sometimes the result of this is a very awkward, technically difficult to execute pattern.\n\nTo the right is a depiction of a simpler polyrhythm of 16ths and 12ths.", Image = THEME:GetPathG("", "Patterns/polyrhythms"), }, { - Name = "Graces / Flams", - ShortDescription = "A little extra flare", - Description = "Grace notes are slightly offset notes, exceptionally rarely forming minijacks, which represent a kind of grace or extra flare to an initial note.\n\nIn musical theory, these are defined as not so necessary, but typically when these are charted it means that a grace note was present in the music.\n\nFlams are made up of graces. Within this game, both usually mean the same. Graces usually break down to be a single chord, and can rarely contain chords themselves.", + Name = "Graces", Image = THEME:GetPathG("", "Patterns/graces"), }, { Name = "Runningman", - ShortDescription = "Anchored stream", - Description = "Classically, runningman is a term referring to a stream that is anchored. We expand on that definition by allowing chords to be mixed in very lightly. An anchored jumpstream can technically contain a runningman, but is more likely to just be referred to as anchored jumpstream.\n\nIt is required that the anchor in a runningman be offset from the rest of the pattern so that it doesn't form chords with the rest of the pattern.\n\nTo the right is a runningman anchored on column 1. The off-taps may be on any column, but it is important that not too many taps be on the same hand as the anchor.", Image = THEME:GetPathG("", "Patterns/runningman"), }, }, ["Hotkeys"] = { { - Name = "Global Hotkeys", - ShortDescription = "Hotkeys available anywhere", - Description = "F2 -- Reload Textures & Metrics\nF2 + Shift -- Reload Metrics\nF2 + Ctrl -- Reload Scripts\nF2 + Shift + Ctrl -- Reload Overlay Screens\nF3 -- Debug Menu (many shortcut options within)\nF9 -- Toggle author-defined metadata transliteration\nAlt + Enter -- Fullscreen Toggle\nTab -- Speed up animations x4\n~ -- Slow down animations x4\nPause|Break -- Toggle menu sounds\nPrintScreen -- Screenshot", - Image = nil, + Name = "GlobalHotkeys", }, { - Name = "SelectMusic Hotkeys", - ShortDescription = "Hotkeys only in song selection", - Description = "F1 -- Song Search\nCtrl + Q -- Load new song folders\nShift + Ctrl + R -- Reload current song folder\nShift + Ctrl + P -- Reload current pack folder\nCtrl + F -- Favorite chart toggle\nCtrl + M -- Permanent mirror chart toggle\nCtrl + G -- Create goal on current chart\nCtrl + O -- Toggle practice mode\nCtrl + S -- Save profile\nCtrl + P -- Create playlist\nCtrl + A -- Add current chart to selected playlist\nCtrl + Number -- If main box active, access the top right buttons. If not, access main box tabs.\nNumber -- Switch tabs in main box/settings\nEscape/Back -- In side box context, exit to main box\nCtrl + L -- Login/Logout\nSpace -- General Tab/Settings Chart Preview toggle\nRight Click -- Pause music toggle if functionality not overridden", - Image = nil, + Name = "SelectMusicHotkeys", }, { - Name = "Gameplay Hotkeys", - ShortDescription = "Hotkeys only in regular gameplay", - Description = "Hold Enter -- Force Fail\nF4 -- Undo sync changes before saving them\nF6 -- Toggle through Autosync Song, Autosync Machine\nF7 -- Toggle claps\nLeftShift + F7 -- Toggle metronome\nF8 -- Toggle autoplay\nF11 -- Move song offset earlier\nAlt + F11 -- Move song offset earlier (small increment)\nF12 -- Move song offset later\nAlt + F12 -- Move song offset later (small increment)\nShift + F11 -- Move global offset earlier\nAlt + Shift + F11 -- Move global offset earlier (small increment)\nShift + F12 -- Move global offset later\nAlt + Shift + F12 -- Move global offset later (small increment)", - Image = nil, + Name = "GameplayHotkeys", }, { - Name = "Customize Gameplay Hotkeys", - ShortDescription = "Hotkeys only in gameplay customization", - Description = "Enter -- Select element or Deselect element\nDelete/Backspace/RestartGameplay -- Undo only the most recent change\nCtrl + Undo -- Reset selected element to default\nRight Click -- Deselect element\nDirectional -- Menu movement or selected element movement\nShift + Directional -- Smaller increment movement\nSpace -- Scroll through movement types of selected element", - Image = nil, + Name = "CustomizeGameplayHotkeys", }, { - Name = "Practice Hotkeys", - ShortDescription = "Hotkeys only in practice mode", - Description = "Backspace -- Jump to loop region start or bookmarked position\nEffectUp -- Increase rate 0.05x\nEffectDown -- Decrease rate 0.05x\nInsertCoin -- Set bookmark position or loop region boundaries\nInsertCoin twice while paused -- Reset loop region to a bookmark position\nMousewheel Scrolling -- If paused, move song position in fine increments\nRight Click -- Toggle pause\nLeft Click Graph -- Jump to position\nRight Click Graph -- Set bookmark or loop region boundaries", - Image = nil, + Name = "PracticeHotkeys", }, { - Name = "Replay Hotkeys", - ShortDescription = "Hotkeys only in replays", - Description = "InsertCoin -- Toggle pause\n\nMust be paused before using any of the following:\nAlt + EffectUp -- Set bookmark position\nAlt + EffectDown -- Go to bookmark position\nShift + EffectUp -- Increase rate 0.05x\nShift + EffectDown -- Decrease rate 0.05x\nEffectUp -- Move song position 5 seconds\nCtrl + EffectUp -- Move song position 0.1 seconds\nEffectDown -- Move song position -5 seconds\nCtrl + EffectDown -- Move song position -0.01 seconds", - Image = nil, + Name = "ReplayHotkeys", }, { - Name = "Evaluation Hotkeys", - ShortDescription = "Hotkeys only in the evaluation screen", - Description = "Ctrl + L -- Login/Logout\nUp/Down -- Scroll through column highlight settings\nEffectUp -- Increase display judge\nEffectDown -- Decrease display judge\nSelect -- Screenshot\nLeft + Right -- Screenshot", - Image = nil, + Name = "EvaluationHotkeys", }, { - Name = "Multiplayer Hotkeys", - ShortDescription = "Hotkeys only in multiplayer", - Description = "Multiplayer isn't finished!", - Image = nil, + Name = "MultiplayerHotkeys", } }, ["How-To"] = { { - Name = "Create Charts", - ShortDescription = "Notes to noises", - Description = "You need an editor. Etterna doesn't currently come with an editor. The popular choices are ArrowVortex and DDReam. Others also choose to use the osu editor or older SM3/SM5 editors.\n\nWhat matters is you have a way to place notes and get them to a valid format like .sm.\n\nA chart only requires audio and the metadata file (.sm for example) to load. Be careful not to attempt to load the chart before both of these are present in your Etterna Songs folder.\n\nMore extensive tutorials on chart creation exist online, and most people are willing to help if you ask around.", - Image = nil, + Name = "HowToCreateCharts", }, { - Name = "Manual Song Install", - ShortDescription = "When downloading in client isn't your thing", - Description = "Here's the scenario: you've created or downloaded a single song or a pack of songs. Now you need to make them load in the game.\n\nIdeally, the folders are structured in this pattern - /Packname/Songname/stuff.sm\n\nIf this applies to a pack you just downloaded, all you must do is extract the pack folder and place it in your Songs folder. The structure is then /Songs/Packname/Songname/stuff.sm.\n\nIf you have a single song, you should create a new pack folder for it in the Songs folder. It can have any name. After all of this is completed, either reopen the game or press Ctrl + Q in SelectMusic.\n\nIf for some reason you want to keep your install separate from your songs, open Preferences.ini and add a direct path to a new Songs folder in the AdditionalSongFolders field.", - Image = nil, + Name = "HowToManualSongInstall", }, { - Name = "Download Packs", - ShortDescription = "How to press a button", - Description = "Ingame, downloading packs is very simple. If you have no packs installed, you may be led first to the core bundle select screen which shows a few sets of packs of varying difficulty to get you started.\n\nIf you skipped that, don't want the bundles, or already have something installed, you can use the downloader screen in SelectMusic. In the top right, in the Ctrl + 3 menu, you should find every pack you could download from ingame. If this list is blank, you may not have an internet connection.\n\nThere are other sources of packs if these downloads ever fail which you must ask around for.\n\nDownloaded packs will extract and install automatically when finished. If it appears that they finish but nothing happens, the download may have failed instead.", - Image = nil, + Name = "HowToDownloadPacks", }, { - Name = "Song Search", - ShortDescription = "Finding the song", - Description = "You may have been expecting to be able to search for a song that you don't have installed. Let's get that out of the way first - it isn't currently possible from within the client.\n\nYou can search for songs that are installed using the F1 menu (the leftmost button in the top right of SelectMusic). The interface should be simple to use. Just fill out the fields you care for and hit enter, and the results come to you.\n\nOtherwise, places that host packs may offer search capabilities.", - Image = nil, + Name = "HowToSongSearch", }, { - Name = "Song Filter", - ShortDescription = "Filtering the songs", - Description = "The song filter is integrated with song search. It can be found in the F1 menu (the leftmost button in the top right of SelectMusic).\n\nThere is not currently any keyboard compatibility with this menu, but the sliders should be sufficient to let you set up a filter with your mouse. A slider placed at an extreme end is considered effectively 0 or infinite, a disabled bound.\n\nFilters stick if you happen to enter a song and come back, unlike the song search.", - Image = nil, + Name = "HowToSongFilter", }, { - Name = "Sortmodes", - ShortDescription = "Sorting the songs", - Description = "The song wheel can be resorted in different predefined ways.\n\nTry pressing up-down-up-down in the main area, and it changes your wheel into a menu to select a sortmode. Some people will find some sortmodes more useful than others.\n\nMost of the time, Group sort is used because it is the natural order everyone expects. Some sorts are for more informational purposes.\n\nIf you would like to modify the behavior of these sortmodes, check out the implementation in Scripts/WheelDataManager.", - Image = nil, + Name = "HowToSortmode", }, { - Name = "Customize Gameplay", - ShortDescription = "Power at your fingertips", - Description = "Customize Gameplay is the gameplay screen which allows you to modify every element on the screen in almost any way to make it fit to your standard.\n\nOn the right side is the navigation and information panel which can be dragged around for visibility. The arrow keys can be used if the mouse is not preferred.\n\nEnter to select a highlighted element, or click an element to select it. Use space to change which movement type you are modifying (coordinates vs sizing). Some elements do not offer more than one type. The mouse can be used to drag around any element.\n\nHold shift to move with smaller increments. Use RestartGameplay to undo or hold Ctrl with it to reset to default.\n\nAll changes are saved to disk as soon as you exit the screen.", - Image = nil, + Name = "HowToCustomizeGameplay", }, { - Name = "Update Etterna", - ShortDescription = "Backup your user data", - Description = "Updating Etterna is typically a painless process on all platforms. In all cases, we would recommend you take a backup of any content you directly added to the game - Noteskins, Save, Assets. Songs do not need to be backed up.\n\nOn Windows, the installer may ask for you to uninstall the old version, and the uninstaller can fail. It's safe to ignore that. As long as you are not directly overlaying the latest version on top of the old one, your new install will run fine.\n\nOn Mac, updating is simply reinstalling the game again, but with less configuration.\n\nOn Linux, updating can be moving to the latest binary or a git pull and rebuild.\n\nThe most important folder you never want to lose is the entire Save folder. Nearly every file in this folder is related to user scores or settings in some way.", - Image = nil, + Name = "HowToUpdate", }, { - Name = "Set Sync/Offset", - ShortDescription = "Notes follow music, you know", - Description = "Every player will experience an issue at some point which manifests in their tap offsets being generally late or generally early. This translates to a late or early mean. In any scenario, a negative offset or mean indicates 'early.'\n\nIf you suffer from an unplayable offset or a consistently bad mean (> 5-10ms +/-) here's a few things to try.\nEtterna offers a visual offset (also called the judge offset), a global (machine) offset, and a song offset. The song offset is set by each chart author, and if it ever ends up wrong, that tends to be their fault and not yours.\nMoving the visual offset moves the visual position where a perfect hit is relative to your receptors. To change it, find it in the F3 menu or in the SelectMusic settings.\nGlobal offset applies to all songs in addition to the song offset. It changes the position of the audio relative to the notes. Ideally, it is 0ms, but can be nonzero if you have some audio/monitor/input related discrepancies.\nGlobal and song offsets can be set automatically by going into a song and pressing F6, then playing to the best of your ability. Try not to let autosync run more than 2 iterations.\nYou may also try moving them manually with F11/F12.", - Image = nil, + Name = "HowToSetSync", }, { - Name = "Change Theme", - ShortDescription = "It's not called a skin", - Description = "The general look of the game is called a Theme. Most of it is written in Lua.\n\nTo install a theme, you just extract its folder into the Themes folder of your install. You shouldn't ever have to backup this folder.\n\nTo change your theme, you can find the option in SelectMusic settings, or in Display Options. It won't look the same as this theme though.", - Image = nil, + Name = "HowToChangeTheme", }, { - Name = "Change Language", - ShortDescription = "We need translators", - Description = "Etterna comes with a partial translation into a few popular languages, but overall none of them are nearly as sufficient as we would like them to be.\n\nTranslation support is always on our mind, but not a very high priority.\n\nTo change language and see what things look like, find it in Display Options or in SelectMusic settings.", - Image = nil, + Name = "HowToChangeLanguage", }, { - Name = "Toggle Menu Sounds", - ShortDescription = "Beep", - Description = "Sometimes menu sounds are annoying.\n\nTo turn them off, press Pause on your keyboard, or find the option in the F3 menu F5 page or in SelectMusic settings.", - Image = nil, + Name = "HowToToggleMenuSound", }, { - Name = "Toggle Pitch Rates", - ShortDescription = "Nightcore Remix", - Description = "Some players enjoy high pitch noises more than others, and some players are better when the song is just faster but not high pitched.\n\nTo toggle pitch usage on rates, find it in the F3 menu F8 page, Advanced Options, or SelectMusic settings.", - Image = nil, + Name = "HowToTogglePitchRates", }, { - Name = "Swap Wheel Side", - ShortDescription = "Change is bad", - Description = "Understandably, some people are bound to not like the fact that the wheel defaults to the left side in Rebirth.\n\nTo swap sides, find the wheel position option in SelectMusic settings > Graphics > Theme Options.", - Image = nil, + Name = "HowToSwapWheelSide", }, { - Name = "Login", - ShortDescription = "Using Online Functionality", - Description = "Login is required if you ever want to upload scores or view leaderboards.\n\nTo begin the login process, you click the broken link in the top left or press Ctrl + L while in SelectMusic. Doing the same again will log you out.\n\nLogging in this way is not required to play multiplayer. Instead, you are separately asked to log in to that, if it is required.", - Image = nil, + Name = "HowToLogin", }, { - Name = "Upload Scores", - ShortDescription = "Flex your 89% on Game Time", - Description = "You must first be logged in to upload any score.\n\nEvery time you log in (and if you automatically log in at the start of a session) Etterna will try to upload any scores you have set that have not yet been uploaded. Scores will also attempt to upload immediately after setting a score, even before your profile saves.\n\nOnly scores on ranked charts will be uploaded. You can see if a chart is ranked by checking its leaderboards in the Scores tab.\n\nTo try force uploading, find the upload buttons either in the Profile tab or the Scores tab.\n\nEtterna uploads things in the background, so there is no clear progress indicator. Just trust.\n\nScores worth 0.00 or that are otherwise invalid will not upload.", - Image = nil, + Name = "HowToUpload", }, { - Name = "Favorite Songs", - ShortDescription = "Ear worms", - Description = "Your song library might become huge and Favoriting is a way to keep track of the files you really like. Just press Ctrl + F on a chart and it becomes a Favorite. Do the same again to remove it.\n\nFavorites can be viewed as a playlist or in the Favorites sortmode if you press Up-Down-Up-Down.", - Image = nil, + Name = "HowToFavoriteSongs", }, { - Name = "Permanently Mirror Charts", - ShortDescription = "Hand bias bad", - Description = "Some charts out there are very biased toward one hand, and some players have particularly bad hands. Because Etterna calculates based on physical difficulty and mirroring a chart is still equivalent because only the hands are swapped, mirroring is a core feature of the game and is ranked.\n\nSome charts might need to always be mirrored for some players, but the players might not want to leave mirror on for everything. Permamirror is the solution.\n\nTo permanently toggle mirror on a specific chart, hover it and press Ctrl + M. Every time you open it, mirror will be on.", - Image = nil, + Name = "HowToPermamirror", }, }, ["Information"] = { { - Name = "About Keymodes", - ShortDescription = "Styles, StyleTypes, StepsTypes, Games ...", - Description = "At its root, this game is a simulator for several other real games. This is why keymodes are separated by Game, and then further by Style.\n\nDance - The core game. 4k. Dance-double can be found here, and is 8k. Also contains a 3k type.\nSolo - Separated from the core game, 6k.\nBeat - The BMS game. 5k+1, 7k+1, and doubles for both.\nKb7 - A gamemode that didn't take off, 7k.\nPump - 5k, 6k, and 10k in single, halfdouble, and doubles.\nPopn - Yes, popn. 5k and 9k.\n\nWithin a game, each style is visible in the difficulty displays. You can switch game in SelectMusic settings or the Select Game screen in Options.", - Image = nil, + Name = "AboutKeymodes", + }, + { + Name = "AboutCleartypes", }, { - Name = "Old Key Config", - ShortDescription = "You shouldn't need this", - Description = "Old key config can still be accessed through the main menu options. The left half of the screen is where the relevant controls are - it's the Player 1 side. The right half is for Player 2, but now those controls are dead. The default columns cannot be modified directly.\n\nTo unbind a default control, rebind that key to a different button on the right side that is infrequently used.\n\nIf you only use the key rebinding screen in Rebirth, you never have to use this screen.\n\nBe aware - just because this screen allows you to bind the same button to multiple keys to play with does not mean that setting scores using that kind of setup is allowed. The feature is meant more for people with a particular playstyle or restriction.", - Image = nil, + Name = "LegacyKeyConfig", }, { - Name = "Replays", - ShortDescription = "Stuck in the past", - Description = "Local and online replays can be viewed for scores where valid replay data is present.\n\nLocal replays can be viewed if the replay is present in Replays or ReplaysV2. You have to find the score in the scores tab, and then click the button to view the replay.\n\nOnline replays can be viewed straight from the chart leaderboards.\n\nWhile in a replay, you can pause and change rates or seek around. The large progress bar can be used as a seeking bar.\n\nEvaluation will show a reconstruction of the actual score's evaluation screen.", - Image = nil, + Name = "ReplayInfo", }, { - Name = "SelectMusic Tips", - ShortDescription = "Speedy menu navigation", - Description = "SelectMusic contains a long list of hotkeys that make navigation quick. Memorizing many of them will be very helpful. Find the page on SelectMusic hotkeys to learn more.\n\nCertain parts of the UI have extra mouse functionality. Clicking the header of the wheel will randomly pick a group or a song in the current group. Clicking certain text in the Overall page of the profile tab toggles the displayed information. Clicking the banner of a song opens chart preview.\n\nThe music wheel scroll bar can be clicked or dragged to quickly navigate through songs. Right clicking scores in the profile tab invalidates them.\n\nEscape is a very useful button to exit the side menus that come up when using the buttons at the top of the screen.", - Image = nil, + Name = "SelectMusicTips", }, { - Name = "Profile Tab Usage", - ShortDescription = "Your Profile and You", - Description = "The Profile tab contains most relevant information about your game usage and scores. The Overall section gives a glance at online and offline ratings as well as general stats. Here, you can upload all scores (that haven't been uploaded) or revalidate all scores locally. You can also click the Player Ratings text to switch it to Player Stats for more information.\n\nIn the View Recent Scores button, or any of the other tabs, you can view several hundred of your scores organized by whichever condition the tab specializes in. Stream for example sorts everything by stream. Recent scores sorts them by date.", - Image = nil, + Name = "ProfileTab", }, { - Name = "Goals Tab Usage", - ShortDescription = "Strive to be better eventually", - Description = "The Goals tab contains a listing of goals you created on charts which you intend to eventually reach. That's the nature of a goal. By default, all goals start at priority 1, rate 1x, and 93%. These attributes can be clicked to increase or decrease them.\n\nTo create a goal, there's a button for it in the tab or you can use Ctrl + G.\n\nThe top buttons of the tab are for sorting the list of goals. The rightmost button filters the list by complete status.\n\nA vacuous goal simply means that the goal is pointless because you have already set a score that beats it. Remove it or make a higher goal.\n\nGoals save to your XML.", - Image = nil, + Name = "GoalsTab", }, { - Name = "Playlists Tab Usage", - ShortDescription = "'Courses'", - Description = "The Playlists tab lets you create multiple lists of charts to play or refer back to. These don't actually have to be used to play in succession like a course, but can serve to be lists of files.\n\nTo create a playlist, Ctrl + P can be used or you can use the New Playlist button. Then click a playlist name to enter it.\n\nTo add charts to the selected playlist, use Ctrl + A or click the Add Current Chart button. The rate a chart gets played on in a course playback can be changed if you click the rate in the detail list.\n\nA playlist cannot be reordered.\n\nPlaylists save to your XML.", - Image = nil, + Name = "PlaylistsTab", }, { - Name = "Tags Tab Usage", - ShortDescription = "Describe your charts", - Description = "The Tags tab lets you put description tags on charts so you can either describe them in your own way or filter based on the tags.\n\nAny number of tags can be assigned to a chart. Assigned tags (up to a certain amount) will show up in the General tab, and also as a different color in the Tags tab.\n\nThe Require Tag button sets a filter on all songs that requires the tag is assigned. The Hide Tag button does the opposite - any song with that tag is not visible. You must click Apply to set these filters.\n\nTo assign tags to a chart, just click the Assign button then click some tags.\n\nDeleting tags is a 2 step process started by clicking Delete.\n\nThe Reset button resets all filters. It does not delete any tags.\n\nTags are saved in a tags.lua file which can be shared with other people.", - Image = nil, + Name = "TagsTab", }, { - Name = "Getting Support", - ShortDescription = "Not for spoonfeeding", - Description = "Sometimes getting Etterna set up or getting things fixed is not a simple process. Well ... it is to a lot of us, but not everyone.\n\nSince many people know the solution to a lot of common issues, if you ever need help, you are free to ask around in the Etterna communities for help. Github issues (can be found on the Title Screen) is a place to report bugs, not ask for help.\n\nDiscord servers that have answers to your questions can be found on the front page of the Github repo, or any website associated with this game.", - Image = nil, + Name = "GettingSupport", }, }, ["Troubleshooting"] = { { Name = "Softlocked", - ShortDescription = "Locked in", - Description = "In some rare conditions, not just in Rebirth, the game can lock but not hard crash or freeze. You can tell that this is what is happening if some buttons might work, but you can't advance or move or go back.\n\nThe instant solution to a softlock is Ctrl + Operator. By default, Operator is set to Scroll Lock. It can be rebound in the old key config. Pressing this combo will send you to the options menu.\n\nF3 + F8 + 9 will also put you in old key config.\n\nIf you ever end up in a softlock condition, it is helpful to be able to consistently reproduce and then describe how you did it in detail in a Github issue so that we can patch it.", - Image = nil, }, { - Name = "All Input Broke", - ShortDescription = "The menu just laughs at you", - Description = "Rebirth has some input quirks which can one way or another cause your menu navigation to completely stop working or work incorrectly.\n\nTo solve this, you can first try to escape back to the main menu. If not possible or you are already there, try reloading scripts and then overlays - Ctrl + F2 and then Ctrl + Shift F2. Then reload the screen by pressing F3 + F6 + 2.\n\nIf you ever end up in this scenario, it is very helpful to report it.", - Image = nil, + Name = "InputBroke", }, { - Name = "General Tips", - ShortDescription = "Blanket fixes", - Description = "Lots of random things happen in this game. Here's some things to try before crying about it.\n\nRebirth locks, input issues, and error spam can be temporarily solved usually by reloading scripts, overlays, and the current screen. Ctrl + F2 > Ctrl + Shift F2 > F3 + F6 + 2. When developing on this theme especially, you will want to know this combo.\n\nCtrl + Operator or F3 + F8 + 9 will get you out of any softlock.\n\nIf input or the graphics don't work for some reason, rebooting is usually a fix.\n\nConstant crashing on startup is usually caused by putting random garbage in pack folders or 0 BPM related issues.", - Image = nil, + Name = "GeneralTips", }, { - Name = "Song Doesn't Load", - ShortDescription = "Mysterious", - Description = "Sometimes when creating charts, authors find that the chart they are working on never appears. There's a reason for this (it's mostly a bug)\n\nIf you put music into a song folder without a .sm and restart or Ctrl + Q at any point, the folder is now forever ignored as not a song directory. The same applies if you put a .sm in that folder but it contains no charts.\n\nTo be safe, you should put audio with the .sm and a valid chart in before restarting or using Ctrl + Q. This will load the new song fine.\n\nIf this situation ever comes up, to solve it you must either delete the Cache folder or rename the song folder.", - Image = nil, + Name = "SongDoesntLoad", }, { - Name = "Song Doesn't Update", - ShortDescription = "When you don't know features", - Description = "When editing charts, authors may run into an issue where the notedata they set is updated when they go to playtest, but the song ends early or late. Or none of the metadata updates to what they saved it as.\n\nThe reason for this is that the game has a cache which it typically blindly trusts. It loads new notedata from disk when going into gameplay, but will not modify chart properties based on that notedata.\n\nTo fix this, hover the song and press Ctrl + Shift + R. That will update the song from disk.", - Image = nil, + Name = "SongDoesntUpdate", }, { - Name = "Scores Don't Save", - ShortDescription = "Rare bugs or game misuse", - Description = "There are a couple of scenarios you may find yourself in if scores stop saving.\n\nThe usual one is that you've accidentally turned off Save Scores. This is an option that is found somewhere in the menus. It normally shouldn't be turned off.\n\nAnother is a rare bug called 0x where in the evaluation somehow your music rate is set to 0x, and now the likelihood that the rest of the session doesn't save is very high. To fix, just restart.\n\nThe last is a faulty install. You installed in a location where you don't have write permissions, such as Program Files. Or you ran out of disk space.", - Image = nil, + Name = "ScoresDontSave", }, { - Name = "Scores Worth 0.00", - ShortDescription = "Invalid scores", - Description = "Scores become worth 0 instantly when the score is invalid upon creation.\n\nConditions for invalid scores:\nNegative BPMs or Warps\nInvalid modifiers (it is obvious which ones are being used)\nFile has less than 200 notes\nFailed\nChord Cohesion On\nAutoplay or Practice\nCertain lua mods active", - Image = nil, + Name = "ScoresWorth0", }, { - Name = "Random Crashing", - ShortDescription = "That's life", - Description = "Sometimes the game crashes. Crashdumps should be generated in a folder within your Program folder.\n\nIf you opt in to crash uploading, you should just let us know in an issue or a report on Discord that you are having crash issues. Otherwise, still let us know but be ready to supply us with the associated .dmp file and logs.\n\nIf you keep crashing for no clear reason, it's always good to submit an issue or ask the community what is happening.", - Image = nil, + Name = "RandomCrashes", }, }, } @@ -516,14 +354,20 @@ local function helpMenu() for _, cat in ipairs(categoryDefs) do items[#items+1] = { isCategory = true, - Name = cat, + Name = THEME:HasString("ScreenHelpMenu", "Category"..cat) and THEME:GetString("ScreenHelpMenu", "Category"..cat) or cat, } for __, optionDef in ipairs(optionDefs[cat]) do + local defname = optionDef.Name items[#items+1] = { isCategory = false, Parent = cat, - Name = optionDef.Name, - Def = optionDef, + Name = THEME:HasString("ScreenHelpMenu", defname) and THEME:GetString("ScreenHelpMenu", defname) or defname, + Def = { + Name = THEME:HasString("ScreenHelpMenu", defname) and THEME:GetString("ScreenHelpMenu", defname) or defname, + ShortDescription = THEME:HasString("ScreenHelpMenu", defname.."ShortDescription") and THEME:GetString("ScreenHelpMenu", defname.."ShortDescription") or optionDef.ShortDescription, + Description = THEME:HasString("ScreenHelpMenu", defname.."Description") and THEME:GetString("ScreenHelpMenu", defname.."Description") or defname.Description, + Image = optionDef.Image, + }, } end end @@ -809,7 +653,7 @@ local function helpMenu() end else self:zoom(subtitleTextSize) - self:settext("Select an item on the left to get info.\nScroll through the list for more categories.") + self:settext(translations["Instruction"]) self:wrapwidthpixels((rightAreaWidth - actuals.EdgeBuffer) / subtitleTextSize) end end, @@ -896,13 +740,13 @@ local t = Def.ActorFrame { self:zoom(infoTextSize) self:maxheight((actuals.InfoHeight - (actuals.InfoVerticalBuffer*2)) / infoTextSize) self:wrapwidthpixels(textw / infoTextSize) - self:settext("Help") + self:settext(translations["Title"]) end, SelectedItemMessageCommand = function(self, params) if params and params.category ~= nil then self:settext(params.category) else - self:settext("Help") + self:settext(translations["Title"]) end end }, @@ -950,7 +794,7 @@ local t = Def.ActorFrame { end, MouseOverCommand = function(self, params) self:diffusealpha(buttonHoverAlpha) - TOOLTIP:SetText("Exit") + TOOLTIP:SetText(translations["Exit"]) TOOLTIP:Show() end, MouseOutCommand = function(self, params) diff --git a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/_chartPreview.lua b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/_chartPreview.lua new file mode 100644 index 0000000000..49a183319e --- /dev/null +++ b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/_chartPreview.lua @@ -0,0 +1,506 @@ +local ratios = { + Width = 780 / 1920, + Height = 971 / 1080, + TopLipHeight = 44 / 1080, + EdgePadding = 13 / 1920, -- distance from left and right edges for everything + DividerThickness = 2 / 1080, -- consistently 2 pixels basically + LowerLipHeight = 34 / 1080, + DensityGraphHeight = 53 / 555, + + RateTextLeftGap = 330 / 1920, + BPMTextLeftGap = 210 / 1920, + BPMNumberLeftGap = 265 / 1920, -- from right edge to right edge of numbers + BPMWidth = 50 / 1920, -- from right edge of bpm number to right edge of bpm text + LengthTextLeftGap = 10 / 1920, + LengthNumberLeftGap = 110 / 1920, -- from right edge to right edge of numbers + LengthWidth = 62 / 1920, -- from right edge of len number to right edge of len text +} + +local actuals = { + Width = ratios.Width * SCREEN_WIDTH, + Height = ratios.Height * SCREEN_HEIGHT, + TopLipHeight = ratios.TopLipHeight * SCREEN_HEIGHT, + EdgePadding = ratios.EdgePadding * SCREEN_WIDTH, + DividerThickness = ratios.DividerThickness * SCREEN_HEIGHT, + LowerLipHeight = ratios.LowerLipHeight * SCREEN_HEIGHT, + DensityGraphHeight = ratios.DensityGraphHeight * SCREEN_HEIGHT, + + RateTextLeftGap = ratios.RateTextLeftGap * SCREEN_WIDTH, + BPMTextLeftGap = ratios.BPMTextLeftGap * SCREEN_WIDTH, + BPMNumberLeftGap = ratios.BPMNumberLeftGap * SCREEN_WIDTH, + BPMWidth = ratios.BPMWidth * SCREEN_WIDTH, + LengthTextLeftGap = ratios.LengthTextLeftGap * SCREEN_WIDTH, + LengthNumberLeftGap = ratios.LengthNumberLeftGap * SCREEN_WIDTH, + LengthWidth = ratios.LengthWidth * SCREEN_WIDTH, +} + +local translations = { + CloseChartPreview = THEME:GetString("ChartPreview", "CloseChartPreview"), + Length = THEME:GetString("ScreenSelectMusic CurSongBox", "Length"), + BPM = THEME:GetString("ScreenSelectMusic CurSongBox", "BPM"), +} + +local lastusedsong = nil +local visibleframeX = 0 -- this number is reset by SetPosition +local visibleframeY = SCREEN_HEIGHT - actuals.Height +local hiddenframeX = SCREEN_WIDTH +local animationSeconds = 0.1 +local focused = false + +local buttonAlpha = 0.1 +local buttonTextSize = 0.95 +local buttonHoverAlpha = 0.6 +local textzoomFudge = 5 +local textsize = 0.8 + +local t = Def.ActorFrame { + Name = "ChartPreviewFile", + InitCommand = function(self) + -- hide chart preview to start + SCUFF.preview.active = false + self:playcommand("SetPosition") + self:y(visibleframeY) + self:diffusealpha(0) + end, + PlayerInfoFrameTabSetMessageCommand = function(self, params) + -- if we ever get this message we need to hide the frame and just exit. + focused = false + SCUFF.preview.active = false + self:finishtweening() + self:smooth(animationSeconds) + self:diffusealpha(0) + self:x(hiddenframeX) + end, + GeneralTabSetMessageCommand = function(self, params) + -- if we ever get this message we need to hide the frame and just exit. + focused = false + SCUFF.preview.active = false + self:finishtweening() + self:smooth(animationSeconds) + self:diffusealpha(0) + self:x(hiddenframeX) + end, + ChartPreviewToggleMessageCommand = function(self, params) + if not focused then + self:diffusealpha(1) + self:finishtweening() + self:sleep(0.01) + self:queuecommand("FinishFocusing") + self:smooth(animationSeconds) + self:x(visibleframeX) + else + -- if toggled twice, send back to the general tab + self:sleep(0.02):queuecommand("ExitPreview") + end + end, + ExitPreviewCommand = function(self) + MESSAGEMAN:Broadcast("GeneralTabSet", {tab = SCUFF.generaltabindex}) + end, + FinishFocusingCommand = function(self) + focused = true + + if SCUFF.preview.active then + -- chart preview turning on + if not SCUFF.preview.resetmusic and lastusedsong ~= nil then + local top = SCREENMAN:GetTopScreen() + if top.PlayCurrentSongSampleMusic then + -- reset music, force start, force full length + SCUFF.preview.resetmusic = true + SOUND:StopMusic() + top:PlayCurrentSongSampleMusic(true, true) + end + end + self:diffusealpha(1) + CONTEXTMAN:SetFocusedContextSet(SCREENMAN:GetTopScreen():GetName(), "Main1") + else + -- chart preview turning off + self:diffusealpha(0) + -- hide in case you are hovering the graph + TOOLTIP:Hide() + end + end, + SetPositionCommand = function(self) + if getWheelPosition() then + visibleframeX = SCREEN_WIDTH + hiddenframeX = SCREEN_WIDTH + actuals.Width + else + visibleframeX = actuals.Width + hiddenframeX = -actuals.Width + end + if focused then + self:x(visibleframeX) + else + self:x(hiddenframeX) + end + end, + UpdateWheelPositionCommand = function(self) + self:playcommand("SetPosition") + end, + OptionUpdatedMessageCommand = function(self, params) + if params and params.name == "Music Wheel Position" then + self:playcommand("UpdateWheelPosition") + end + end, + WheelSettledMessageCommand = function(self, params) + -- should trigger if wheel stops moving + self:playcommand("LoadNoteData", {song = params.song, steps = params.steps}) + lastusedsong = params.song + + SCUFF.preview.resetmusic = false + if lastusedsong ~= nil and SCUFF.preview.active then + local top = SCREENMAN:GetTopScreen() + if top.PlayCurrentSongSampleMusic then + -- reset music, force start, force full length + SCUFF.preview.resetmusic = true + SOUND:StopMusic() + top:PlayCurrentSongSampleMusic(true, true) + end + end + self:playcommand("Set", {song = params.song, group = params.group, hovered = params.hovered, steps = params.steps}) + end, + ChangedStepsMessageCommand = function(self, params) + -- should trigger only if switching steps, not when switching songs + self:playcommand("LoadNoteData", {song = GAMESTATE:GetCurrentSong(), steps = params.steps}) + lastusedsong = GAMESTATE:GetCurrentSong() + self:playcommand("Set", {song = GAMESTATE:GetCurrentSong(), hovered = lastusedsong, steps = params.steps}) + end, + CurrentRateChangedMessageCommand = function(self) + self:playcommand("Set", {song = GAMESTATE:GetCurrentSong(), hovered = lastusedsong, steps = GAMESTATE:GetCurrentSteps()}) + end, +} + +local notefieldYCenter = (actuals.Height - actuals.DensityGraphHeight) / 2 -- this is technically wrong BUT WORKS +local aspectRatioProportion = (16/9) / (SCREEN_WIDTH / SCREEN_HEIGHT) -- this was designed for 16:9 so compensate +local notefieldZoomBaseline = 1 -- zoom for 4key width +local notefieldWidthBaseline = 256 -- 4key width +local notefieldLengthPixels = actuals.Height - actuals.DensityGraphHeight - 15 -- this isnt a perfect number but it fits for our use and i dont know how to calculate it +local notefieldAllowBeyondReceptorPixels = 0 -- this shouldnt be changed +local notefieldYReversePixelsBase = 0 -- this means when reverse is toggled the notefield moves itself. dont let it do that + +-- this function makes no sense btw. none of the math is actually based on anything +-- find a replacement if you are going to mess with it +local function getSizeForStyle() + local style = GAMESTATE:GetCurrentStyle() + if style == nil then return notefieldZoomBaseline, notefieldLengthPixels / notefieldZoomBaseline end + + local stylewidth = style:GetWidth() + -- the assumption is that a width of notefieldWidthBaseline uses a zoom of notefieldZoomBaseline + -- and notefieldLengthPixels is 300 for that baseline zoom + -- find a zoom and pixel length that fits using math + local pdiff = stylewidth / notefieldWidthBaseline + + -- i replaced these with the defaults because the area given was so big + -- unreplace them if for some reason this becomes a problem + local newzoom = 1--notefieldZoomBaseline / pdiff / aspectRatioProportion + local newlength = notefieldLengthPixels-- / newzoom + + return newzoom, newlength +end + +t[#t+1] = UIElements.QuadButton(1, 1) .. { + Name = "BG", + InitCommand = function(self) + self:halign(1):valign(0) + self:zoomto(actuals.Width, actuals.Height) + registerActorToColorConfigElement(self, "chartPreview", "Background") + end, + MouseDownCommand = function(self, params) + local top = SCREENMAN:GetTopScreen() + if params.event ~= "DeviceButton_left mouse button" then + if top.PauseSampleMusic then + top:PauseSampleMusic() + end + end + end +} + +t[#t+1] = UIElements.TextButton(2, 2, "Common Normal") .. { + Name = "CloseChartPreview", + InitCommand = function(self) + self.txt = self:GetChild("Text") + self.bg = self:GetChild("BG") + self.txt:valign(0) + self.txt:settext(translations["CloseChartPreview"]) + self.txt:zoom(buttonTextSize) + self.bg:x(-self.txt:GetZoomedWidth() * 0.025) + self.bg:y(self.txt:GetZoomedHeight() / 2) + self.bg:zoomto(self.txt:GetZoomedWidth() * 1.05, self.txt:GetZoomedHeight() * 1.3) + self.bg:diffusealpha(buttonAlpha) + self:y(actuals.DensityGraphHeight + actuals.EdgePadding) + + self.alphaDeterminingFunction = function(self) + if isOver(self.bg) then + self:diffusealpha(buttonHoverAlpha) + else + self:diffusealpha(1) + end + end + end, + SetPositionCommand = function(self) + if getWheelPosition() then + self.bg:halign(0) + self.txt:halign(0) + self:x(-actuals.Width + actuals.EdgePadding) + else + self.bg:halign(1) + self.txt:halign(1) + self:x(-actuals.EdgePadding) + end + end, + RolloverUpdateCommand = function(self, params) + self:alphaDeterminingFunction() + end, + ClickCommand = function(self, params) + if params.update == "OnMouseDown" then + self:GetParent():playcommand("ExitPreview") + self:alphaDeterminingFunction() + end + end, +} + +t[#t+1] = Def.ActorFrame { + Name = "CopyPastedCurSongBoxLine", + InitCommand = function(self) + self:x(-actuals.Width + actuals.EdgePadding) + self:y(actuals.Height - actuals.EdgePadding) + end, + + LoadFont("Common Normal") .. { + Name = "MSDLabel", + InitCommand = function(self) + self:x(actuals.LengthTextLeftGap) + self:y(-actuals.LowerLipHeight - actuals.EdgePadding) + self:halign(0) + self:zoom(textsize) + self:maxwidth((actuals.Width) / textsize - textzoomFudge) + self:settext("MSD") + end, + }, + Def.RollingNumbers { + Name = "MSD", + Font = "Common Normal", + BeginCommand = function(self) + self:y(-actuals.LowerLipHeight - actuals.EdgePadding) + self:halign(0) + self:zoom(textsize) + self:x(actuals.EdgePadding + self:GetParent():GetChild("MSDLabel"):GetZoomedWidth()) + self:maxwidth((actuals.Width - self:GetParent():GetChild("MSDLabel"):GetZoomedWidth()) / textsize - textzoomFudge) + self:Load("RollingNumbers2Decimal") + end, + SetCommand = function(self, params) + if params.steps then + local meter = params.steps:GetMSD(getCurRateValue(), 1) + self:targetnumber(meter) + self:diffuse(colorByMSD(meter)) + else + self:targetnumber(0) + self:diffuse(color("1,1,1,1")) + end + end + }, + + UIElements.TextButton(1, 1, "Common Normal") .. { + Name = "Rate", + InitCommand = function(self) + self:x(actuals.RateTextLeftGap) + local txt = self:GetChild("Text") + local bg = self:GetChild("BG") + + txt:halign(0):valign(1) + txt:zoom(textsize) + txt:maxwidth((actuals.Width - actuals.RateTextLeftGap) / textsize - textzoomFudge) + registerActorToColorConfigElement(txt, "main", "PrimaryText") + bg:halign(0):valign(1) + bg:zoomy(actuals.LowerLipHeight) + end, + SetCommand = function(self, params) + local txt = self:GetChild("Text") + local bg = self:GetChild("BG") + local str = string.format("%.2f", getCurRateValue()) .. "x" + txt:settext(str) + bg:zoomx(txt:GetZoomedWidth()) + end, + ClickCommand = function(self, params) + if self:IsInvisible() then return end + if params.update == "OnMouseDown" then + if params.event == "DeviceButton_left mouse button" then + changeMusicRate(1, true) + elseif params.event == "DeviceButton_right mouse button" then + changeMusicRate(-1, true) + end + end + end, + RolloverUpdateCommand = function(self, params) + if self:IsInvisible() then return end + if params.update == 'in' then + self:diffusealpha(buttonHoverAlpha) + else + self:diffusealpha(1) + end + end, + MouseScrollMessageCommand = function(self, params) + if self:IsInvisible() then return end + if isOver(self:GetChild("BG")) then + if params.direction == "Up" then + changeMusicRate(1, true) + elseif params.direction == "Down" then + changeMusicRate(-1, true) + end + end + end + }, + + LoadFont("Common Normal") .. { + Name = "LengthText", + InitCommand = function(self) + self:halign(0):valign(1) + self:x(actuals.LengthTextLeftGap) + self:zoom(textsize) + self:maxwidth((actuals.LengthNumberLeftGap) / textsize - textzoomFudge) + self:settext(translations["Length"]) + registerActorToColorConfigElement(self, "main", "PrimaryText") + end + }, + LoadFont("Common Normal") .. { + Name = "LengthNumbers", + InitCommand = function(self) + self:halign(0):valign(1) + self:x(actuals.LengthNumberLeftGap) + self:zoom(textsize) + self:maxwidth((actuals.BPMTextLeftGap - actuals.LengthNumberLeftGap) / textsize - textzoomFudge) + self:settext("55:55") + end, + SetCommand = function(self, params) + if params.steps then + local len = GetPlayableTime() + self:settext(SecondsToMMSS(len)) + self:diffuse(colorByMusicLength(len)) + else + self:settext("--:--") + self:diffuse(color("1,1,1,1")) + end + end + }, + + LoadFont("Common Normal") .. { + Name = "BPMText", + InitCommand = function(self) + self:halign(0):valign(1) + self:x(actuals.BPMTextLeftGap) + self:zoom(textsize) + self:maxwidth((actuals.BPMNumberLeftGap - actuals.BPMTextLeftGap) / textsize - textzoomFudge) + self:settext(translations["BPM"]) + registerActorToColorConfigElement(self, "main", "PrimaryText") + end + }, + Def.BPMDisplay { + File = THEME:GetPathF("Common", "Normal"), + Name = "BPMDisplay", + InitCommand = function(self) + self:halign(0):valign(1) + self:x(actuals.BPMNumberLeftGap) + self:zoom(textsize) + self:maxwidth(actuals.BPMWidth / textsize - textzoomFudge) + end, + SetCommand = function(self, params) + if params.steps then + self:visible(true) + self:SetFromSteps(params.steps) + else + self:visible(false) + end + end + }, +} + +t[#t+1] = Def.NoteFieldPreview { + Name = "NoteField", + DrawDistanceBeforeTargetsPixels = notefieldLengthPixels / notefieldZoomBaseline, + DrawDistanceAfterTargetsPixels = notefieldAllowBeyondReceptorPixels, -- notes disappear at the receptor + + InitCommand = function(self) + self:playcommand("SetPosition") + self:y(notefieldYCenter) + self:zoom(notefieldZoomBaseline) + -- make mods work + self:SetFollowPlayerOptions(true) + self:SetUpdateFunction(function(self) + ArrowEffects.Update() + end) + end, + BeginCommand = function(self) + -- we need to redo the draw order for the notefield and graph + -- the notefield ends up being on top of everything in the actorframe otherwise + self:draworder(1) + self:GetParent():GetChild("ChordDensityGraphFile"):draworder(2) + self:GetParent():SortByDrawOrder() + end, + SetPositionCommand = function(self) + if getWheelPosition() then + self:x(-actuals.Width / 2) + else + self:x(-actuals.Width / 2) + end + end, + LoadNoteDataCommand = function(self, params) + local steps = params.steps + if steps ~= nil then + self:LoadNoteData(steps, true) + else + self:LoadDummyNoteData() + end + local z, l = getSizeForStyle() + self:zoom(z) + self:playcommand("SetPosition") + self:SetConstantMini(ReceptorSizeToMini(z)) + -- running from what you fear brings you yet closer to that which you loathe + -- magic numbers rule the world. never forget it. + local compensation = getPlayerOptions():UsingReverse() and (notefieldYCenter * z) or (-notefieldYCenter/2 * z) + self:y(notefieldYCenter + compensation) + self:UpdateDrawDistance(notefieldAllowBeyondReceptorPixels, l) + self:UpdateYReversePixels(notefieldYReversePixelsBase) + end, + OptionUpdatedMessageCommand = function(self, params) + if params ~= nil then + -- listen for the notedata modifying mods being toggled and apply their changes immediately + local options = { + Mirror = true, + Turn = true, + ["Pattern Transform"] = true, + ["Hold Transform"] = true, + Remove = true, + Insert = true, + Mines = true, + ["Scroll Direction"] = true, + } + if options[params.name] ~= nil then + self:playcommand("LoadNoteData", {steps = GAMESTATE:GetCurrentSteps()}) + end + + if params.name == "Music Wheel Position" then + self:playcommand("SetPosition") + end + end + end, +} + +t[#t+1] = LoadActorWithParams("../chordDensityGraph.lua", {sizing = { + Width = actuals.Width, + Height = actuals.DensityGraphHeight, + NPSThickness = 2, + TextSize = 0.65, +}}) .. { + InitCommand = function(self) + self:x(-actuals.Width) + end, + LoadNoteDataCommand = function(self, params) + local steps = params.steps + if steps ~= nil then + self:playcommand("LoadDensityGraph", {steps = steps, song = params.song}) + else + self:playcommand("LoadDensityGraph", {steps = steps, song = params.song}) + end + end +} + +return t diff --git a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/curSongBox.lua b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/curSongBox.lua index 8773bece60..598d2cd42d 100644 --- a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/curSongBox.lua +++ b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/curSongBox.lua @@ -19,12 +19,20 @@ local t = Def.ActorFrame { ChangedStepsMessageCommand = function(self, params) self:playcommand("Set", {song = GAMESTATE:GetCurrentSong(), hovered = lastHovered, steps = params.steps}) end, + OptionUpdatedMessageCommand = function(self, params) + if params and params.name == "Show Banners" then + self:playcommand("Set", {song = GAMESTATE:GetCurrentSong(), hovered = lastHovered, steps = GAMESTATE:GetCurrentSteps()}) + end + end, GeneralTabSetMessageCommand = function(self) focused = true end, PlayerInfoFrameTabSetMessageCommand = function(self) focused = false - end + end, + ChartPreviewToggleMessageCommand = function(self) + focused = false + end, } local ratios = { @@ -100,6 +108,11 @@ do actuals.BannerAreaHeight = ratios.BannerHeight * SCREEN_HEIGHT end +local translations = { + Length = THEME:GetString("ScreenSelectMusic CurSongBox", "Length"), + BPM = THEME:GetString("ScreenSelectMusic CurSongBox", "BPM"), +} + local textsize = 0.8 local textzoomFudge = 5 @@ -178,7 +191,7 @@ t[#t+1] = Def.ActorFrame { -- if it fails, probably nothing was there to receive the message or the tree is bad if SCUFF.generaltab == SCUFF.generaltabindex and focused and params.event == "DeviceButton_left mouse button" then SCUFF.preview.active = not SCUFF.preview.active - self:GetParent():GetParent():GetParent():playcommand("ToggleChartPreview") + MESSAGEMAN:Broadcast("ChartPreviewToggle") elseif params.event == "DeviceButton_right mouse button" then local top = SCREENMAN:GetTopScreen() if top.PauseSampleMusic then @@ -224,7 +237,9 @@ t[#t+1] = Def.ActorFrame { self:diffusealpha(1) if params.song then local bnpath = params.song:GetBannerPath() - if not bnpath then + if not showBanners() then + self:visible(false) + elseif not bnpath then bnpath = THEME:GetPathG("Common", "fallback banner") self:visible(false) else @@ -233,7 +248,9 @@ t[#t+1] = Def.ActorFrame { self:LoadBackground(bnpath) else local bnpath = WHEELDATA:GetFolderBanner(params.hovered) - if not bnpath or bnpath == "" then + if not showBanners() then + self:visible(false) + elseif not bnpath or bnpath == "" then bnpath = THEME:GetPathG("Common", "fallback banner") self:visible(false) else @@ -358,7 +375,7 @@ t[#t+1] = Def.ActorFrame { self:xy(actuals.LengthTextLeftGap, actuals.Height - actuals.TextLowerGap1) self:zoom(textsize) self:maxwidth((actuals.LengthNumberLeftGap - actuals.LeftTextLeftGap) / textsize - textzoomFudge) - self:settext("LENGTH") + self:settext(translations["Length"]) registerActorToColorConfigElement(self, "main", "PrimaryText") end }, @@ -390,7 +407,7 @@ t[#t+1] = Def.ActorFrame { self:xy(actuals.BPMTextLeftGap, actuals.Height - actuals.TextLowerGap1) self:zoom(textsize) self:maxwidth((actuals.BPMNumberLeftGap - actuals.BPMTextLeftGap) / textsize - textzoomFudge) - self:settext("BPM") + self:settext(translations["BPM"]) registerActorToColorConfigElement(self, "main", "PrimaryText") end }, @@ -404,12 +421,9 @@ t[#t+1] = Def.ActorFrame { self:maxwidth(actuals.BPMWidth / textsize - textzoomFudge) end, SetCommand = function(self, params) - -- it appears that SetFromSteps is broken... - -- note to self. - -- wow i forgot about this. time to forget about it again -11 months later if params.steps then self:visible(true) - self:SetFromSong(params.song) + self:SetFromSteps(params.steps) else self:visible(false) end diff --git a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/default.lua b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/default.lua index 7128b7a0b2..c12120406c 100644 --- a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/default.lua +++ b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/default.lua @@ -49,6 +49,13 @@ t[#t+1] = Def.ActorFrame { self:x(hiddenX) TOOLTIP:Hide() end, + ChartPreviewToggleMessageCommand = function(self) + rightFrameVisible = false + self:finishtweening() + self:smooth(0.1) + self:x(hiddenX) + TOOLTIP:Hide() + end, UpdateWheelPositionCommand = function(self) self:playcommand("SetThePositionForThisFrameNothingElse") end, @@ -66,4 +73,6 @@ t[#t+1] = Def.ActorFrame { }), } +t[#t+1] = LoadActor("_chartPreview.lua") + return t \ No newline at end of file diff --git a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalBox.lua b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalBox.lua index 13112d85c8..8532907925 100644 --- a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalBox.lua +++ b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalBox.lua @@ -32,12 +32,12 @@ local actuals = { -- the page names in the order they go local choiceNames = { - "General", - "Scores", - "Profile", - "Goals", - "Playlists", - "Tags", + THEME:GetString("ScreenSelectMusic Tabs", "General"), + THEME:GetString("ScreenSelectMusic Tabs", "Scores"), + THEME:GetString("ScreenSelectMusic Tabs", "Profile"), + THEME:GetString("ScreenSelectMusic Tabs", "Goals"), + THEME:GetString("ScreenSelectMusic Tabs", "Playlists"), + THEME:GetString("ScreenSelectMusic Tabs", "Tags"), } SCUFF.generaltabcount = #choiceNames SCUFF.generaltab = 1 -- reset generaltab page @@ -128,11 +128,12 @@ local function createChoices() selectedIndex = n MESSAGEMAN:Broadcast("GeneralTabSet", {tab = n}) end - elseif event.DeviceInput.button == "DeviceButton_space" and focused and SCUFF.generaltab == SCUFF.generaltabindex then + elseif event.DeviceInput.button == "DeviceButton_space" and + ((focused and SCUFF.generaltab == SCUFF.generaltabindex) or SCUFF.preview.active) then -- toggle chart preview if the general tab is the current tab visible SCUFF.preview.active = not SCUFF.preview.active -- this should propagate off to the right places - self:GetParent():playcommand("ToggleChartPreview") + MESSAGEMAN:Broadcast("ChartPreviewToggle") end end end) @@ -162,6 +163,11 @@ t[#t+1] = Def.ActorFrame { PlayerInfoFrameTabSetMessageCommand = function(self) focused = false end, + ChartPreviewToggleMessageCommand = function(self) + -- although not focused, ChartPreview activates Main1 input context so that we can go to any tab from it + -- or also press space to come back to the general tab + focused = false + end, Def.Quad { Name = "BG", diff --git a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/_chartPreview.lua b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/_chartPreview.lua deleted file mode 100644 index 0bfb56a8c0..0000000000 --- a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/_chartPreview.lua +++ /dev/null @@ -1,248 +0,0 @@ -local lastusedsong = nil -local t = Def.ActorFrame { - Name = "ChartPreviewFile", - InitCommand = function(self) - -- hide chart preview to start - SCUFF.preview.active = false - self:diffusealpha(0) - end, - WheelSettledMessageCommand = function(self, params) - -- should trigger if wheel stops moving - self:playcommand("LoadNoteData", {song = params.song, steps = params.steps}) - lastusedsong = params.song - - SCUFF.preview.resetmusic = false - if lastusedsong ~= nil and SCUFF.preview.active then - local top = SCREENMAN:GetTopScreen() - if top.PlayCurrentSongSampleMusic then - -- reset music, force start, force full length - SCUFF.preview.resetmusic = true - SOUND:StopMusic() - top:PlayCurrentSongSampleMusic(true, true) - end - end - end, - ChangedStepsMessageCommand = function(self, params) - -- should trigger only if switching steps, not when switching songs - self:playcommand("LoadNoteData", {song = GAMESTATE:GetCurrentSong(), steps = params.steps}) - lastusedsong = GAMESTATE:GetCurrentSong() - end, - ToggleChartPreviewCommand = function(self, params) - if params ~= nil and params.active ~= nil then - SCUFF.preview.active = params.active - end - - if SCUFF.preview.active then - -- chart preview turning on - if not SCUFF.preview.resetmusic and lastusedsong ~= nil then - local top = SCREENMAN:GetTopScreen() - if top.PlayCurrentSongSampleMusic then - -- reset music, force start, force full length - SCUFF.preview.resetmusic = true - SOUND:StopMusic() - top:PlayCurrentSongSampleMusic(true, true) - end - end - self:diffusealpha(1) - else - -- chart preview turning off - self:diffusealpha(0) - -- hide in case you are hovering the graph - TOOLTIP:Hide() - end - end -} - -local ratios = { - DensityGraphHeight = 53 / 555, - NoteFieldHeight = 502 / 555, -} - -local actuals = { - -- some actuals left out here and calculated below instead - -} - --- scoping magic -do - -- copying the provided ratios and actuals tables to have access to the sizing for the overall frame - local rt = Var("ratios") - for k,v in pairs(rt) do - ratios[k] = v - end - local at = Var("actuals") - for k,v in pairs(at) do - actuals[k] = v - end -end - --- expected actual values may not exist for whatever reason, so default to 0 instead of nil error -actuals.LowerLipHeight = actuals.LowerLipHeight or 0 -actuals.Height = actuals.Height or 0 --- the ratio is the percentage of the area we will use, so multiply it by the raw (actual) given area --- when placing, take into account each other (notefield is placed below the density graph) -actuals.DensityGraphHeight = ratios.DensityGraphHeight * (actuals.Height - actuals.LowerLipHeight) -actuals.NoteFieldHeight = ratios.NoteFieldHeight * (actuals.Height - actuals.LowerLipHeight) - - --- relative to the leftmost part of the general box, this is the horizontal center of the notefield -actuals.VerticalDividerLeftGap = actuals.VerticalDividerLeftGap or 0 -actuals.DividerThickness = actuals.DividerThickness or 0 -local rightHalfXBegin = actuals.VerticalDividerLeftGap + actuals.DividerThickness -local notefieldXCenter = rightHalfXBegin + (actuals.Width - rightHalfXBegin) / 2 -local notefieldYCenter = actuals.DensityGraphHeight + actuals.NoteFieldHeight / 2 -local expectedGeneralReceptorHeight = 64 -- this number varies slightly but typically receptors are "64x64" -local aspectRatioProportion = (16/9) / (SCREEN_WIDTH / SCREEN_HEIGHT) -- this was designed for 16:9 so compensate -local notefieldZoomBaseline = 0.8 -- zoom for 4key width -local notefieldWidthBaseline = 256 -- 4key width -local notefieldYOffset = actuals.DensityGraphHeight + expectedGeneralReceptorHeight / 1080 * SCREEN_HEIGHT * notefieldZoomBaseline -local notefieldReverseAdd = actuals.NoteFieldHeight - notefieldYOffset -local notefieldLengthPixels = 300 -- this isnt a perfect number but it fits for our use and i dont know how to calculate it -local notefieldAllowBeyondReceptorPixels = 0 -- this shouldnt be changed -local notefieldYReversePixelsBase = 288 -- this is what it is in gameplay, but it needs to change if we mess with mini/zoom - -local function getSizeForStyle() - local style = GAMESTATE:GetCurrentStyle() - if style == nil then return notefieldZoomBaseline, notefieldLengthPixels / notefieldZoomBaseline end - - local stylewidth = style:GetWidth() - -- the assumption is that a width of notefieldWidthBaseline uses a zoom of notefieldZoomBaseline - -- and notefieldLengthPixels is 300 for that baseline zoom - -- find a zoom and pixel length that fits using math - local pdiff = stylewidth / notefieldWidthBaseline - local newzoom = notefieldZoomBaseline / pdiff / aspectRatioProportion - local newlength = notefieldLengthPixels / newzoom - -- taking new calculated reverse pixel offset and making it smaller by a bit - local newreverse = notefieldYReversePixelsBase / newzoom - local newreversediff = notefieldYReversePixelsBase - (notefieldYReversePixelsBase - newreverse) / 3 - - return newzoom, newlength, newreversediff -end - -t[#t+1] = UIElements.QuadButton(1, 1) .. { - Name = "BG", - InitCommand = function(self) - self:halign(0):valign(0) - self:xy(rightHalfXBegin, actuals.DensityGraphHeight) - self:zoomto(actuals.Width - rightHalfXBegin, actuals.NoteFieldHeight + actuals.LowerLipHeight) - registerActorToColorConfigElement(self, "chartPreview", "Background") - end, - MouseDownCommand = function(self, params) - local top = SCREENMAN:GetTopScreen() - if params.event ~= "DeviceButton_left mouse button" then - if top.PauseSampleMusic then - top:PauseSampleMusic() - end - end - end -} - -t[#t+1] = Def.NoteFieldPreview { - Name = "NoteField", - DrawDistanceBeforeTargetsPixels = notefieldLengthPixels / notefieldZoomBaseline, - DrawDistanceAfterTargetsPixels = notefieldAllowBeyondReceptorPixels, -- notes disappear at the receptor - - InitCommand = function(self) - self:playcommand("SetPosition") - self:y(notefieldYCenter) - self:zoom(notefieldZoomBaseline) - -- make mods work - self:SetFollowPlayerOptions(true) - self:SetUpdateFunction(function(self) - ArrowEffects.Update() - end) - end, - BeginCommand = function(self) - -- we need to redo the draw order for the notefield and graph - -- the notefield ends up being on top of everything in the actorframe otherwise - self:draworder(1) - self:GetParent():GetChild("ChordDensityGraphFile"):draworder(2) - self:GetParent():SortByDrawOrder() - end, - SetPositionCommand = function(self) - -- THESE ARE LITERALLY RANDOM NUMBERS - -- I DO NOT KNOW WHY THIS IS NECESSARY - -- IT DOES NOT MAKE ANY SENSE - if getWheelPosition() then - ms.ok(self:GetZoom()) - self:x((rightHalfXBegin + 75) * self:GetZoom()) - else - self:x(rightHalfXBegin + (actuals.Width - rightHalfXBegin) / 2) - end - end, - LoadNoteDataCommand = function(self, params) - local steps = params.steps - if steps ~= nil then - self:LoadNoteData(steps, true) - else - self:LoadDummyNoteData() - end - local z, l, r = getSizeForStyle() - self:zoom(z) - self:playcommand("SetPosition") - self:SetConstantMini(ReceptorSizeToMini(z)) - -- when changing zoom of the notefield, the receptors change position just like the length needs to - -- so need to move the notefield up or down to compensate for the change in zoom - local compensation = -(actuals.NoteFieldHeight) * (notefieldZoomBaseline-z)/2 - -- running from what you fear brings you yet closer to that which you loathe - -- magic numbers run the world - compensation = compensation + (getPlayerOptions():UsingReverse() and 25 or 0) - self:y(notefieldYCenter - 40 + compensation) - self:UpdateDrawDistance(notefieldAllowBeyondReceptorPixels, l) - self:UpdateYReversePixels(r) - end, - OptionUpdatedMessageCommand = function(self, params) - if params ~= nil then - -- listen for the notedata modifying mods being toggled and apply their changes immediately - local options = { - Mirror = true, - Turn = true, - ["Pattern Transform"] = true, - ["Hold Transform"] = true, - Remove = true, - Insert = true, - Mines = true, - ["Scroll Direction"] = true, - } - if options[params.name] ~= nil then - self:playcommand("LoadNoteData", {steps = GAMESTATE:GetCurrentSteps()}) - end - - if params.name == "Music Wheel Position" then - self:playcommand("SetPosition") - end - end - end, -} - -t[#t+1] = LoadActorWithParams("../../chordDensityGraph.lua", {sizing = { - Width = actuals.Width - rightHalfXBegin, - Height = actuals.DensityGraphHeight, - NPSThickness = 1.5, - TextSize = 0.45, -}}) .. { - InitCommand = function(self) - self:x(rightHalfXBegin) - end, - LoadNoteDataCommand = function(self, params) - local steps = params.steps - if steps ~= nil then - self:playcommand("LoadDensityGraph", {steps = steps, song = params.song}) - else - self:playcommand("LoadDensityGraph", {steps = steps, song = params.song}) - end - end -} - -t[#t+1] = UIElements.QuadButton(1, 1) .. { - Name = "ChoicesCover", - InitCommand = function(self) - self:halign(0):valign(0) - self:xy(rightHalfXBegin, actuals.DensityGraphHeight + actuals.NoteFieldHeight) - self:zoomto(actuals.Width - rightHalfXBegin, actuals.LowerLipHeight) - self:diffuse(color("#000000")) - self:draworder(2):visible(0) - end, -} - -return t diff --git a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/general.lua b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/general.lua index 6903e789aa..ec040f6543 100644 --- a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/general.lua +++ b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/general.lua @@ -119,13 +119,19 @@ do end end +-- translations exclusive to this screen +local translations = { + AverageNPS = THEME:GetString("ScreenSelectMusic General", "AverageNPS"), + NegativeBPMs = THEME:GetString("ScreenSelectMusic General", "NegativeBPMs"), +} + local statNames = { - "Notes", - "Jumps", - "Hands", - "Holds", - "Rolls", - "Mines", + THEME:GetString("RadarCategory", "Notes"), + THEME:GetString("RadarCategory", "Jumps"), + THEME:GetString("RadarCategory", "Hands"), + THEME:GetString("RadarCategory", "Holds"), + THEME:GetString("RadarCategory", "Rolls"), + THEME:GetString("RadarCategory", "Mines"), } -- output of the relevant radars function is in a certain order @@ -144,14 +150,14 @@ local statMapping = { } local msdNames = { - "Average NPS", - "Stream", - "Jumpstream", - "Handstream", - "Stamina", - "JackSpeed", - "Chordjack", - "Technical", + translations["AverageNPS"], + ms.SkillSetsTranslatedByName["Stream"], + ms.SkillSetsTranslatedByName["Jumpstream"], + ms.SkillSetsTranslatedByName["Handstream"], + ms.SkillSetsTranslatedByName["Stamina"], + ms.SkillSetsTranslatedByName["JackSpeed"], + ms.SkillSetsTranslatedByName["Chordjack"], + ms.SkillSetsTranslatedByName["Technical"], } local mainTextSize = 1 @@ -274,7 +280,7 @@ local function createMSDLines() if i == 0 then if params.steps then if params.steps:GetTimingData():HasWarps() then - self:settext("NegBPMs!") + self:settext(translations["NegativeBPMs"]) self:diffusealpha(1) else self:diffusealpha(0) @@ -422,9 +428,6 @@ t[#t+1] = Def.Quad { self:halign(0):valign(0) registerActorToColorConfigElement(self, "main", "SeparationDivider") end, - ToggleChartPreviewCommand = function(self) - self:visible(not SCUFF.preview.active) - end, } t[#t+1] = Def.RollingNumbers { @@ -528,28 +531,35 @@ t[#t+1] = UIElements.SpriteButton(1, 1, nil) .. { self:finishtweening() self.song = params.song if params.song then + self:diffusealpha(1) + + -- load the cdtitle if it is present if params.song:HasCDTitle() then - self:diffusealpha(1) self:Load(params.song:GetCDTitlePath()) + else + -- otherwise, load the invisible (blank) image and stretch it so you can still hover it + self:Load(THEME:GetPathG("", "_blank")) - local h = self:GetHeight() - local w = self:GetWidth() local allowedWidth = actuals.VerticalDividerLeftGap - actuals.CDTitleRightGap - actuals.CDTitleLeftGap - if h >= actuals.CDTitleAllowedHeight and w >= allowedWidth then - if h * (allowedWidth / actuals.CDTitleAllowedHeight) >= w then - self:zoom(actuals.CDTitleAllowedHeight / h) - else - self:zoom(allowedWidth / w) - end - elseif h >= actuals.CDTitleAllowedHeight then + self:zoomto(allowedWidth, actuals.CDTitleAllowedHeight) + return + end + + local h = self:GetHeight() + local w = self:GetWidth() + local allowedWidth = actuals.VerticalDividerLeftGap - actuals.CDTitleRightGap - actuals.CDTitleLeftGap + if h >= actuals.CDTitleAllowedHeight and w >= allowedWidth then + if h * (allowedWidth / actuals.CDTitleAllowedHeight) >= w then self:zoom(actuals.CDTitleAllowedHeight / h) - elseif w >= allowedWidth then - self:zoom(allowedWidth / w) else - self:zoom(1) + self:zoom(allowedWidth / w) end + elseif h >= actuals.CDTitleAllowedHeight then + self:zoom(actuals.CDTitleAllowedHeight / h) + elseif w >= allowedWidth then + self:zoom(allowedWidth / w) else - self:diffusealpha(0) + self:zoom(1) end else self:diffusealpha(0) @@ -585,6 +595,5 @@ t[#t+1] = createStatLines() t[#t+1] = createTopSkillsetLines() t[#t+1] = createMSDLines() t[#t+1] = createTagDisplays() -t[#t+1] = LoadActorWithParams("_chartPreview.lua", {ratios = ratios, actuals = actuals}) return t diff --git a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/goals.lua b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/goals.lua index 28739876ec..2ddd7de795 100644 --- a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/goals.lua +++ b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/goals.lua @@ -77,6 +77,23 @@ do end end +local translations = { + DeleteGoal = THEME:GetString("ScreenSelectMusic Goals", "DeleteGoal"), + AlreadyBeat = THEME:GetString("ScreenSelectMusic Goals", "AlreadyBeat"), + VacuousGoal = THEME:GetString("ScreenSelectMusic Goals", "VacuousGoal"), + AchievedGoal = THEME:GetString("ScreenSelectMusic Goals", "AchievedGoal"), + SetGoal = THEME:GetString("ScreenSelectMusic Goals", "SetGoal"), + PrioritySortDisplay = THEME:GetString("ScreenSelectMusic Goals", "PrioritySortDisplay"), + RateSortDisplay = THEME:GetString("ScreenSelectMusic Goals", "RateSortDisplay"), + MSDSortDisplay = THEME:GetString("ScreenSelectMusic Goals", "MSDSortDisplay"), + NameSortDisplay = THEME:GetString("ScreenSelectMusic Goals", "NameSortDisplay"), + DateSortDisplay = THEME:GetString("ScreenSelectMusic Goals", "DateSortDisplay"), + NewGoal = THEME:GetString("ScreenSelectMusic Goals", "NewGoal"), + FilterShowAll = THEME:GetString("ScreenSelectMusic Goals", "FilterShowAll"), + FilterComplete = THEME:GetString("ScreenSelectMusic Goals", "FilterComplete"), + FilterIncomplete = THEME:GetString("ScreenSelectMusic Goals", "FilterIncomplete"), +} + local goalLine1TextSize = 0.85 local goalLine2TextSize = 0.75 local pageTextSize = 0.7 @@ -527,6 +544,18 @@ local function goalList() self:diffusealpha(1) end end, + GoalsUpdatedMessageCommand = function(self) + -- ONLY TRIGGERED BY CTRL+G + -- MAKE SURE THIS MIMICS THE NEW GOAL BUTTON + + -- this will load the new goal into the list and keep the page where it already was + local pagebefore = page + profile:SetFromAll() + resortGoals() + page = clamp(pagebefore, 1, maxPage) + self:playcommand("UpdateGoalList") + self:playcommand("UpdateText") + end, Def.Quad { Name = "BG", @@ -802,7 +831,7 @@ local function goalList() else if isOver(self) then self:diffusealpha(buttonHoverAlpha) - TOOLTIP:SetText("Delete Goal") + TOOLTIP:SetText(translations["DeleteGoal"]) TOOLTIP:Show() else self:diffusealpha(1) @@ -827,7 +856,7 @@ local function goalList() end, MouseOverCommand = function(self) if self:IsInvisible() then return end - TOOLTIP:SetText("Delete Goal") + TOOLTIP:SetText(translations["DeleteGoal"]) TOOLTIP:Show() self:diffusealpha(buttonHoverAlpha) end, @@ -899,13 +928,13 @@ local function goalList() if status == "Achieved" then when = extractDateFromDateString(goal:WhenAchieved()) elseif status == "Vacuous" then - when = "- Already Beat" + when = "- " .. translations["AlreadyBeat"] else -- Created/Set when = extractDateFromDateString(goal:WhenAssigned()) end - self:settextf("%s %s", status, when) + self:settextf("%s %s", translations[status.."Goal"], when) end } } @@ -930,7 +959,7 @@ local function goalList() { -- Sort by Priority Name = "prioritysort", Type = "Exclusive", - Display = {"Priority"}, + Display = {translations["PrioritySortDisplay"]}, IndexGetter = function() return 1 end, Condition = function() return true end, TapFunction = function() @@ -946,7 +975,7 @@ local function goalList() { -- Sort by Rate Name = "ratesort", Type = "Exclusive", - Display = {"Rate"}, + Display = {translations["RateSortDisplay"]}, IndexGetter = function() return 1 end, Condition = function() return true end, TapFunction = function() @@ -962,7 +991,7 @@ local function goalList() { -- Sort by MSD Name = "msdsort", Type = "Exclusive", - Display = {"MSD"}, + Display = {translations["MSDSortDisplay"]}, IndexGetter = function() return 1 end, Condition = function() return true end, TapFunction = function() @@ -978,7 +1007,7 @@ local function goalList() { -- Sort by Song (Song + ChartKey) Name = "namesort", Type = "Exclusive", - Display = {"Name"}, + Display = {translations["NameSortDisplay"]}, IndexGetter = function() return 1 end, Condition = function() return true end, TapFunction = function() @@ -994,7 +1023,7 @@ local function goalList() { -- Sort by Set Date Name = "datesort", Type = "Exclusive", - Display = {"Date"}, + Display = {translations["DateSortDisplay"]}, IndexGetter = function() return 1 end, Condition = function() return true end, TapFunction = function() @@ -1010,7 +1039,7 @@ local function goalList() { -- New Goal on current Chart Name = "newgoal", Type = "Tap", - Display = {"New Goal"}, + Display = {translations["NewGoal"]}, IndexGetter = function() return 1 end, Condition = function() return true end, TapFunction = function() @@ -1033,7 +1062,7 @@ local function goalList() { -- Toggle between All, Completed, and Incomplete Goals Name = "filtergoals", Type = "Toggle", - Display = {"Showing All", "Showing Complete", "Showing Incomplete"}, + Display = {translations["FilterShowAll"], translations["FilterComplete"], translations["FilterIncomplete"]}, IndexGetter = function() if visibleGoalType == "All" then return 1 diff --git a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/playlists.lua b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/playlists.lua index dbb136c95b..569bd13c21 100644 --- a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/playlists.lua +++ b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/playlists.lua @@ -81,6 +81,17 @@ do end end +local translations = { + PlayAsCourse = THEME:GetString("ScreenSelectMusic Playlists", "PlayAsCourse"), + DeletePlaylist = THEME:GetString("ScreenSelectMusic Playlists", "DeletePlaylist"), + DeleteChart = THEME:GetString("ScreenSelectMusic Playlists", "DeleteChart"), + NumberOfCharts = THEME:GetString("ScreenSelectMusic Playlists", "NumberOfCharts"), + AverageMSD = THEME:GetString("ScreenSelectMusic Playlists", "AverageMSD"), + NewPlaylist = THEME:GetString("ScreenSelectMusic Playlists", "NewPlaylist"), + AddCurrentChart = THEME:GetString("ScreenSelectMusic Playlists", "AddCurrentChart"), + Back = THEME:GetString("ScreenSelectMusic Playlists", "Back"), +} + -- playlist list sizing local itemLine1TextSize = 0.85 local itemLine2TextSize = 0.75 @@ -259,7 +270,7 @@ local function playlistList() else if isOver(self) then self:diffusealpha(buttonHoverAlpha) - TOOLTIP:SetText("Play As Course") + TOOLTIP:SetText(translations["PlayAsCourse"]) TOOLTIP:Show() else self:diffusealpha(1) @@ -274,7 +285,7 @@ local function playlistList() end, MouseOverCommand = function(self) if self:IsInvisible() then return end - TOOLTIP:SetText("Play As Course") + TOOLTIP:SetText(translations["PlayAsCourse"]) TOOLTIP:Show() self:diffusealpha(buttonHoverAlpha) end, @@ -303,7 +314,7 @@ local function playlistList() else if isOver(self) then self:diffusealpha(buttonHoverAlpha) - TOOLTIP:SetText("Delete Playlist\n(Triggers a Save!)") + TOOLTIP:SetText(translations["DeletePlaylist"]) TOOLTIP:Show() else self:diffusealpha(1) @@ -326,7 +337,7 @@ local function playlistList() end, MouseOverCommand = function(self) if self:IsInvisible() then return end - TOOLTIP:SetText("Delete Playlist\n(Triggers a Save!)") + TOOLTIP:SetText(translations["DeletePlaylist"]) TOOLTIP:Show() self:diffusealpha(buttonHoverAlpha) end, @@ -348,7 +359,7 @@ local function playlistList() end, UpdateTextCommand = function(self) if playlist == nil then return end - self:settextf("Number of charts: %d", playlist:GetNumCharts()) + self:settextf("%s: %d", translations["NumberOfCharts"], playlist:GetNumCharts()) end }, LoadFont("Common Normal") .. { @@ -363,7 +374,7 @@ local function playlistList() end, UpdateTextCommand = function(self) if playlist == nil then return end - self:settextf("(Average MSD %5.2f)", playlist:GetAverageRating()) + self:settextf("(%s %5.2f)", translations["AverageMSD"], playlist:GetAverageRating()) end } } @@ -620,7 +631,7 @@ local function playlistList() else if isOver(self) then self:diffusealpha(buttonHoverAlpha) - TOOLTIP:SetText("Delete Chart\n(Triggers a Save!)") + TOOLTIP:SetText(translations["DeleteChart"]) TOOLTIP:Show() else self:diffusealpha(1) @@ -638,7 +649,7 @@ local function playlistList() end, MouseOverCommand = function(self) if self:IsInvisible() then return end - TOOLTIP:SetText("Delete Chart\n(Triggers a Save!)") + TOOLTIP:SetText(translations["DeleteChart"]) TOOLTIP:Show() self:diffusealpha(buttonHoverAlpha) end, @@ -777,7 +788,7 @@ local function playlistList() { -- Make a new playlist or add the current chart to the opened playlist Name = "newentry", Type = "Tap", - Display = {"New Playlist", "Add Current Chart"}, + Display = {translations["NewPlaylist"], translations["AddCurrentChart"]}, IndexGetter = function() if inPlaylistDetails then return 2 @@ -822,7 +833,7 @@ local function playlistList() { -- Exit the page that lets you see inside a playlist Name = "back", Type = "Tap", - Display = {"Back"}, + Display = {translations["Back"]}, IndexGetter = function() return 1 end, Condition = function() return inPlaylistDetails end, TapFunction = function() diff --git a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/profile.lua b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/profile.lua index 04c684eafb..f979df74c7 100644 --- a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/profile.lua +++ b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/profile.lua @@ -106,6 +106,29 @@ do end end +local translations = { + SongsLoaded = THEME:GetString("ScreenSelectMusic Profile", "SongsLoaded"), + PacksLoaded = THEME:GetString("ScreenSelectMusic Profile", "PacksLoaded"), + CountVisible = THEME:GetString("ScreenSelectMusic Profile", "CountVisible"), + JudgeDifficulty = THEME:GetString("ScreenSelectMusic Profile", "JudgeDifficulty"), + Top3PlayedSkillsets = THEME:GetString("ScreenSelectMusic Profile", "Top3PlayedSkillsets"), + UploadAllScores = THEME:GetString("ScreenSelectMusic Profile", "UploadAllScores"), + ValidateAllScores = THEME:GetString("ScreenSelectMusic Profile", "ValidateAllScores"), + Plays = THEME:GetString("ScreenSelectMusic Profile", "Plays"), + ArrowsSmashed = THEME:GetString("ScreenSelectMusic Profile", "ArrowsSmashed"), + Playtime = THEME:GetString("ScreenSelectMusic Profile", "Playtime"), + ScoreStats = THEME:GetString("ScreenSelectMusic Profile", "ScoreStats"), + PackLamps = THEME:GetString("ScreenSelectMusic Profile", "PackLamps"), + ScoreUploadMayBeSlow = THEME:GetString("ScreenSelectMusic Profile", "ScoreUploadMayBeSlow"), + OnlineServer = THEME:GetString("ScreenSelectMusic Profile", "OnlineServer"), + PlayerRatings = THEME:GetString("ScreenSelectMusic Profile", "PlayerRatings"), + OnlineSlashOffline = THEME:GetString("ScreenSelectMusic Profile", "OnlineSlashOffline"), + PlayerStats = THEME:GetString("ScreenSelectMusic Profile", "PlayerStats"), + ViewRecentScores = THEME:GetString("ScreenSelectMusic Profile", "ViewRecentScores"), + ShowingLocalScores = THEME:GetString("ScreenSelectMusic Profile", "ShowingLocalScores"), + ShowingOnlineScores = THEME:GetString("ScreenSelectMusic Profile", "ShowingOnlineScores"), +} + -- the page names in the order they go -- it happens to literally just be the skillsets including Overall local choiceNames = ms.SkillSets @@ -163,7 +186,7 @@ local function createChoices() self:x((actuals.Width / #choiceNames) * (i-1) + (actuals.Width / #choiceNames / 2)) txt:zoom(choiceTextSize) txt:maxwidth(actuals.Width / #choiceNames / choiceTextSize - textzoomFudge) - txt:settext(choiceNames[i]) + txt:settext(ms.SkillSetsTranslatedByName[choiceNames[i]]) registerActorToColorConfigElement(txt, "main", "PrimaryText") bg:zoomto(actuals.Width / #choiceNames, actuals.LowerLipHeight) end, @@ -635,44 +658,44 @@ local function createList() -- songs loaded function(self) local count = SONGMAN:GetNumSongs() - self:settextf("%d songs loaded", count) + self:settextf("%d %s", count, translations["SongsLoaded"]) end, -- song packs installed (and filtered) function(self) local packcount = SONGMAN:GetNumSongGroups() local groupcount = #WHEELDATA:GetAllGroups() if packcount ~= groupcount then - self:settextf("%d packs loaded (%d visible)", packcount, groupcount) + self:settextf("%d %s (%d %s)", packcount, translations["PacksLoaded"], groupcount, translations["CountVisible"]) else - self:settextf("%d packs loaded", packcount) + self:settextf("%d %s", packcount, translations["PacksLoaded"]) end end, -- current judge function(self) local judge = GetTimingDifficulty() - self:settextf("Judge: %d", judge) + self:settextf("%s: %d", translations["JudgeDifficulty"], judge) end, -- a line break function(self) end, -- top skillset plays header function(self) - self:settext("Top 3 Played Skillsets") + self:settext(translations["Top3PlayedSkillsets"]) end, -- top played skillset function(self) local count, name = getSkillsetPlaysByPosition(1) - self:settextf("%s (%d)", name, count) + self:settextf("%s (%d)", ms.SkillSetsTranslatedByName[name], count) end, -- 2nd top played skillset function(self) local count, name = getSkillsetPlaysByPosition(2) - self:settextf("%s (%d)", name, count) + self:settextf("%s (%d)", ms.SkillSetsTranslatedByName[name], count) end, -- 3rd top played skillset function(self) local count, name = getSkillsetPlaysByPosition(3) - self:settextf("%s (%d)", name, count) + self:settextf("%s (%d)", ms.SkillSetsTranslatedByName[name], count) end, -- blank function(self) @@ -680,33 +703,33 @@ local function createList() -- Upload all scores button function(self) if DLMAN:IsLoggedIn() then - self:settext("Upload all scores to EO") + self:settext(translations["UploadAllScores"]) else self:settext("") end end, -- Validate all scores button function(self) - self:settext("Validate all scores") + self:settext(translations["ValidateAllScores"]) end, }, Right = { -- playcount function(self) local pcount = SCOREMAN:GetTotalNumberOfScores() - self:settextf("%d plays", pcount) + self:settextf("%d %s", pcount, translations["Plays"]) end, -- arrow count function(self) local parrows = profile:GetTotalTapsAndHolds() -- shorten if over 1 million since the number is kind of long local nstr = shortenIfOver1Mil(parrows) - self:settextf("%s arrows smashed", nstr) + self:settextf("%s %s", nstr, translations["ArrowsSmashed"]) end, -- playtime (overall, not gameplay) function(self) local ptime = profile:GetTotalSessionSeconds() - self:settextf("%s playtime", SecondsToHHMMSS(ptime)) + self:settextf("%s %s", SecondsToHHMMSS(ptime), translations["Playtime"]) end, -- empty padding function(self) @@ -715,32 +738,32 @@ local function createList() end, -- score stats function(self) - self:settextf("Score Stats:") + self:settextf("%s:", translations["ScoreStats"]) end, -- AAAAA count function(self) local quints = WHEELDATA:GetTotalClearsByGrade("Grade_Tier01") - self:settextf("AAAAAs: %d", quints) + self:settextf("%ss: %d", getGradeStrings("Grade_Tier01"), quints) end, -- AAAA count function(self) local scores = WHEELDATA:GetTotalClearsByGrade("Grade_Tier02") + WHEELDATA:GetTotalClearsByGrade("Grade_Tier03") + WHEELDATA:GetTotalClearsByGrade("Grade_Tier04") - self:settextf("AAAAs: %d", scores) + self:settextf("%ss: %d", getGradeStrings("Grade_Tier04"), scores) end, -- AAA count function(self) local scores = WHEELDATA:GetTotalClearsByGrade("Grade_Tier05") + WHEELDATA:GetTotalClearsByGrade("Grade_Tier06") + WHEELDATA:GetTotalClearsByGrade("Grade_Tier07") - self:settextf("AAAs: %d", scores) + self:settextf("%ss: %d", getGradeStrings("Grade_Tier07"), scores) end, -- AA count function(self) local scores = WHEELDATA:GetTotalClearsByGrade("Grade_Tier08") + WHEELDATA:GetTotalClearsByGrade("Grade_Tier09") + WHEELDATA:GetTotalClearsByGrade("Grade_Tier10") - self:settextf("AAs: %d", scores) + self:settextf("%ss: %d", getGradeStrings("Grade_Tier10"), scores) end, -- lamp count function(self) local lamps = WHEELDATA:GetTotalLampCount() - self:settextf("Pack Lamps: %d", lamps) + self:settextf("%s: %d", translations["PackLamps"], lamps) end, -- at the cost of your fps to make the game look better @@ -794,7 +817,7 @@ local function createList() function(self) if DLMAN:IsLoggedIn() then self:diffusealpha(buttonHoverAlpha) - TOOLTIP:SetText("May be slow - Will run in background") + TOOLTIP:SetText(translations["ScoreUploadMayBeSlow"]) TOOLTIP:Show() end end, @@ -943,7 +966,7 @@ local function createList() self:diffuse(colorByMSD(rating)) end else - self:settextf("%s:", skillset) + self:settextf("%s:", ms.SkillSetsTranslatedByName[skillset]) end end, UpdateLoginStatusCommand = function(self) @@ -1074,7 +1097,7 @@ local function createList() end, SetCommand = function(self) if DLMAN:IsLoggedIn() then - self:settextf("(EO: %s)", DLMAN:GetUsername()) + self:settextf("(%s: %s)", translations["OnlineServer"], DLMAN:GetUsername()) else self:settext("") end @@ -1109,12 +1132,12 @@ local function createList() if self.ratings then if DLMAN:IsLoggedIn() then - txt:settext("Player Ratings (Online/Offline):") + txt:settextf("%s (%s):", translations["PlayerRatings"], translations["OnlineSlashOffline"]) else - txt:settext("Player Ratings:") + txt:settextf("%s:", translations["PlayerRatings"]) end else - txt:settext("Player Stats:") + txt:settextf("%s:", translations["PlayerStats"]) end bg:zoomto(txt:GetZoomedWidth(), actuals.NameInfoLargeLineSpacing + textzoomFudge) @@ -1151,7 +1174,7 @@ local function createList() self:y(actuals.Height - actuals.InfoUpperMargin) self:zoom(largelineTextSize) self:maxwidth((actuals.Width - actuals.AvatarLeftGap - actuals.RightTextLeftGap) / largelineTextSize - textzoomFudge) - self:settext("View Recent Scores") + self:settext(translations["ViewRecentScores"]) registerActorToColorConfigElement(self, "main", "PrimaryText") end, MouseOverCommand = function(self) @@ -1296,9 +1319,9 @@ local function createList() end if isLocal then - txt:settext("Showing Local") + txt:settext(translations["ShowingLocalScores"]) else - txt:settext("Showing Online") + txt:settext(translations["ShowingOnlineScores"]) end -- itemspacing is probably a good approximation for this button height diff --git a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/scores.lua b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/scores.lua index 123ed72844..d621493911 100644 --- a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/scores.lua +++ b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/scores.lua @@ -174,6 +174,38 @@ do end end +local translations = { + LastScore = THEME:GetString("ScreenSelectMusic Scores", "LastScore"), + You = THEME:GetString("ScreenSelectMusic Scores", "You"), + NoName = THEME:GetString("ScreenSelectMusic Scores", "NoName"), + ShowOffsetPlot = THEME:GetString("ScreenSelectMusic Scores", "ShowOffsetPlot"), + ShowReplay = THEME:GetString("ScreenSelectMusic Scores", "ShowReplay"), + ShowingJudge4Plot = THEME:GetString("ScreenSelectMusic Scores", "ShowingJudge4Plot"), + ScoreBy = THEME:GetString("ScreenSelectMusic Scores", "ScoreBy"), + HowToCloseOffsetPlot = THEME:GetString("ScreenSelectMusic Scores", "HowToCloseOffsetPlot"), + UploadScore = THEME:GetString("ScreenSelectMusic Scores", "UploadScore"), + UploadScorePack = THEME:GetString("ScreenSelectMusic Scores", "UploadScorePack"), + ShowEvaluation = THEME:GetString("ScreenSelectMusic Scores", "ShowEvaluation"), + JudgeDifficulty = THEME:GetString("ScreenSelectMusic Scores", "JudgeDifficulty"), + JudgeJustice = THEME:GetString("ScreenSelectMusic Scores", "JudgeJustice"), + ComboBreakers = THEME:GetString("ScreenSelectMusic Scores", "ComboBreakers"), + MaxCombo = THEME:GetString("ScreenSelectMusic Scores", "MaxCombo"), + DateAchieved = THEME:GetString("ScreenSelectMusic Scores", "DateAchieved"), + ScoreModsUsed = THEME:GetString("ScreenSelectMusic Scores", "ScoreModsUsed"), + NoLocalScoresRecorded = THEME:GetString("ScreenSelectMusic Scores", "NoLocalScoresRecorded"), + ChartUnranked = THEME:GetString("ScreenSelectMusic Scores", "ChartUnranked"), + FetchingScores = THEME:GetString("ScreenSelectMusic Scores", "FetchingScores"), + NoOnlineScoresRecorded = THEME:GetString("ScreenSelectMusic Scores", "NoOnlineScoresRecorded"), + ShowOnlineScores = THEME:GetString("ScreenSelectMusic Scores", "ShowOnlineScores"), + ShowLocalScores = THEME:GetString("ScreenSelectMusic Scores", "ShowLocalScores"), + ShowTopScores = THEME:GetString("ScreenSelectMusic Scores", "ShowTopScores"), + ShowAllScores = THEME:GetString("ScreenSelectMusic Scores", "ShowAllScores"), + HideInvalidScores = THEME:GetString("ScreenSelectMusic Scores", "HideInvalidScores"), + ShowInvalidScores = THEME:GetString("ScreenSelectMusic Scores", "ShowInvalidScores"), + CurrentRateOnly = THEME:GetString("ScreenSelectMusic Scores", "CurrentRateOnly"), + AllRates = THEME:GetString("ScreenSelectMusic Scores", "AllRates"), +} + t[#t+1] = Def.Quad { Name = "UpperLip", InitCommand = function(self) @@ -298,7 +330,6 @@ local function createList() if isLocal then scores = {} localrtTable = getRateTable() - local sng = GAMESTATE:GetCurrentSong() if localrtTable ~= nil then localrates, localrateIndex = getUsedRates(localrtTable) localscoreIndex = 1 @@ -427,6 +458,20 @@ local function createList() local score = nil local scoreIndex = i + -- expecting self to be UIElements.TextButton or a Def.BitmapText + -- the purpose is to color based on CC On + local function diffuseScore(self, category, element) + local txt = self + if self.GetChild ~= nil then + txt = self:GetChild("Text") or self + end + if score ~= nil and score:GetChordCohesion() then + EGGMAN.gegagoogoo(txt, score:GetChartKey()):diffuse(COLORS:getColor("generalBox", "ChordCohesionOnScore")) + else + txt:stopeffect():diffuse(COLORS:getColor(category, element)) + end + end + return Def.ActorFrame { Name = "ScoreItem_"..i, InitCommand = function(self) @@ -490,7 +535,10 @@ local function createList() txt:zoom(rateTextSize) txt:maxwidth(actuals.SSRRateWidth / rateTextSize - textzoomFudge) bg:zoomto(txt:GetZoomedWidth(), txt:GetZoomedHeight() * textButtonHeightFudgeScalarMultiplier) - registerActorToColorConfigElement(txt, "main", "SecondaryText") + diffuseScore(self, "main", "SecondaryText") + end, + ColorConfigUpdatedMessageCommand = function(self) + diffuseScore(self, "main", "SecondaryText") end, SetScoreCommand = function(self) if score ~= nil then @@ -499,6 +547,7 @@ local function createList() local rt = score:GetMusicRate() txt:settext(getRateString(rt)) bg:zoomto(txt:GetZoomedWidth(), txt:GetZoomedHeight() * textButtonHeightFudgeScalarMultiplier) + diffuseScore(self, "main", "SecondaryText") end end, RolloverUpdateCommand = function(self, params) @@ -527,7 +576,10 @@ local function createList() self:x(actuals.LeftCenteredAlignmentLineLeftGap + actuals.LeftCenteredAlignmentDistance) txt:zoom(nameTextSize) txt:maxwidth(actuals.NameJudgmentWidth / nameTextSize - textzoomFudge) - registerActorToColorConfigElement(txt, "main", "PrimaryText") + diffuseScore(self, "main", "PrimaryText") + end, + ColorConfigUpdatedMessageCommand = function(self) + diffuseScore(self, "main", "PrimaryText") end, SetScoreCommand = function(self) if score ~= nil then @@ -535,16 +587,17 @@ local function createList() local bg = self:GetChild("BG") local n = score:GetName() if n == "" then - n = "" + n = translations["NoName"] elseif n == "#P1#" then if score:GetScoreKey() == mostRecentScore:GetScoreKey() then - n = "Last Score" + n = translations["LastScore"] else - n = "You" + n = translations["You"] end end txt:settext(n) bg:zoomto(txt:GetZoomedWidth(), txt:GetZoomedHeight() * textButtonHeightFudgeScalarMultiplier) + diffuseScore(self, "main", "PrimaryText") end end, RolloverUpdateCommand = function(self, params) @@ -576,7 +629,10 @@ local function createList() self:xy(actuals.LeftCenteredAlignmentLineLeftGap + actuals.LeftCenteredAlignmentDistance, actuals.ItemHeight) txt:zoom(judgmentTextSize) txt:maxwidth(actuals.NameJudgmentWidth / judgmentTextSize - textzoomFudge) - registerActorToColorConfigElement(txt, "main", "SecondaryText") + diffuseScore(self, "main", "SecondaryText") + end, + ColorConfigUpdatedMessageCommand = function(self) + diffuseScore(self, "main", "SecondaryText") end, SetScoreCommand = function(self) if score ~= nil then @@ -593,6 +649,7 @@ local function createList() local comboStr = tostring(score:GetMaxCombo()) txt:settextf("%s | %s | %s | %s | %s | %s x%s", jgMaStr, jgPStr, jgGrStr, jgGoStr, jgBStr, jgMiStr, comboStr) bg:zoomto(txt:GetZoomedWidth(), txt:GetZoomedHeight() * textButtonHeightFudgeScalarMultiplier) + diffuseScore(self, "main", "SecondaryText") end end, RolloverUpdateCommand = function(self, params) @@ -646,7 +703,7 @@ local function createList() if self:IsInvisible() then return end if params.update == "in" then if score ~= nil and score:HasReplayData() then - TOOLTIP:SetText("Show Offset Plot") + TOOLTIP:SetText(translations["ShowOffsetPlot"]) TOOLTIP:Show() self:diffusealpha(buttonHoverAlpha) end @@ -684,11 +741,15 @@ local function createList() self:xy(actuals.ItemWidth - actuals.RightInfoRightAlignRightGap, actuals.ItemHeight) self:zoom(dateTextSize) self:maxwidth((actuals.ItemWidth - actuals.RightInfoLeftAlignLeftGap - actuals.RightInfoRightAlignRightGap) / dateTextSize - textzoomFudge) - registerActorToColorConfigElement(self, "main", "SecondaryText") + diffuseScore(self, "main", "SecondaryText") + end, + ColorConfigUpdatedMessageCommand = function(self) + diffuseScore(self, "main", "SecondaryText") end, SetScoreCommand = function(self) if score ~= nil then self:settext(score:GetDate()) + diffuseScore(self, "main", "SecondaryText") end end }, @@ -731,7 +792,7 @@ local function createList() MouseOverCommand = function(self) if self:IsInvisible() then return end self:diffusealpha(buttonHoverAlpha) - TOOLTIP:SetText("Show Replay") + TOOLTIP:SetText(translations["ShowReplay"]) TOOLTIP:Show() end, MouseOutCommand = function(self) @@ -1080,7 +1141,7 @@ local function createList() local wifeStr = checkWifeStr(ws) -- keeping these plots j4 because i dont want to complicate logic for stuff --local judgeSetting = (PREFSMAN:GetPreference("SortBySSRNormPercent") and 4 or table.find(ms.JudgeScalers, notShit.round(score:GetJudgeScale(), 2))) or GetTimingDifficulty() - self:settextf("Showing J4 Plot | Score by: %s | %s", score:GetName(), wifeStr) + self:settextf("%s | %s: %s | %s", translations["ShowingJudge4Plot"], translations["ScoreBy"], score:GetName(), wifeStr) end, }, LoadFont("Common Normal") .. { @@ -1089,7 +1150,7 @@ local function createList() self:xy(actuals.MainGraphicWidth / 2, actuals.OffsetPlotHeight + extrasizing / 2) self:zoom(onlinePlotTextSize) self:maxwidth(((actuals.MainGraphicWidth)) / onlinePlotTextSize) - self:settext("Click this box or do anything to close") + self:settext(translations["HowToCloseOffsetPlot"]) registerActorToColorConfigElement(self, "main", "PrimaryText") end, }, @@ -1228,9 +1289,9 @@ local function createList() if isOver(self) then self:diffusealpha(buttonHoverAlpha) if WHEELDATA:GetCurrentSort() == 1 then - TOOLTIP:SetText("Upload Score\nShift: All in pack") + TOOLTIP:SetText(translations["UploadScorePack"]) else - TOOLTIP:SetText("Upload Score") + TOOLTIP:SetText(translations["UploadScore"]) end TOOLTIP:Show() end @@ -1246,9 +1307,9 @@ local function createList() if self:IsInvisible() then return end self:diffusealpha(buttonHoverAlpha) if WHEELDATA:GetCurrentSort() == 1 then - TOOLTIP:SetText("Upload Score\nShift: All in pack") + TOOLTIP:SetText(translations["UploadScorePack"]) else - TOOLTIP:SetText("Upload Score") + TOOLTIP:SetText(translations["UploadScore"]) end TOOLTIP:Show() end, @@ -1288,7 +1349,7 @@ local function createList() self:diffusealpha(1) if isOver(self) then self:diffusealpha(buttonHoverAlpha) - TOOLTIP:SetText("Show Evaluation") + TOOLTIP:SetText(translations["ShowEvaluation"]) TOOLTIP:Show() end else @@ -1302,7 +1363,7 @@ local function createList() MouseOverCommand = function(self) if self:IsInvisible() then return end self:diffusealpha(buttonHoverAlpha) - TOOLTIP:SetText("Show Evaluation") + TOOLTIP:SetText(translations["ShowEvaluation"]) TOOLTIP:Show() end, MouseOutCommand = function(self) @@ -1336,7 +1397,7 @@ local function createList() self:diffusealpha(1) if isOver(self) then self:diffusealpha(buttonHoverAlpha) - TOOLTIP:SetText("Show Replay") + TOOLTIP:SetText(translations["ShowReplay"]) TOOLTIP:Show() end else @@ -1350,7 +1411,7 @@ local function createList() MouseOverCommand = function(self) if self:IsInvisible() then return end self:diffusealpha(buttonHoverAlpha) - TOOLTIP:SetText("Show Replay") + TOOLTIP:SetText(translations["ShowReplay"]) TOOLTIP:Show() end, MouseOutCommand = function(self) @@ -1395,12 +1456,12 @@ local function createList() end if not judge then judge = 4 end if judge < 4 then judge = 4 end - local js = judge ~= 9 and judge or "Justice" + local js = judge ~= 9 and judge or translations["JudgeJustice"] local perc = checkWifeStr(wife) self:ClearAttributes() self:diffuse(COLORS:getMainColor("PrimaryText")) self:diffusealpha(1) - self:settextf("%s | %s (%s | Judge %s)", ssrstr, perc, wv, js) + self:settextf("%s | %s (%s | %s %s)", ssrstr, perc, wv, translations["JudgeDifficulty"], js) self:AddAttribute(0, {Length = #ssrstr, Diffuse = ssrcolr}) self:AddAttribute(#string.format("%s | ", ssrstr), {Length = #perc, Diffuse = wifecolr}) end @@ -1420,9 +1481,9 @@ local function createList() if localscore ~= nil then local mc = getScoreComboBreaks(localscore) if mc ~= nil then - self:settextf("Combo Breaks: %s", mc) + self:settextf("%s: %s", translations["ComboBreakers"], mc) else - self:settext("Combo Breaks: -") + self:settextf("%s: -", translations["ComboBreakers"]) end end end @@ -1440,7 +1501,7 @@ local function createList() UpdateListCommand = function(self) if localscore ~= nil then local mc = localscore:GetMaxCombo() - self:settextf("Max Combo: %d", mc) + self:settextf("%s: %d", translations["MaxCombo"], mc) end end }, @@ -1457,7 +1518,7 @@ local function createList() UpdateListCommand = function(self) if localscore ~= nil then local d = getScoreDate(localscore) - self:settextf("Date Achieved: %s", d) + self:settextf("%s: %s", translations["DateAchieved"], d) end end }, @@ -1474,7 +1535,7 @@ local function createList() UpdateListCommand = function(self) if localscore ~= nil then local m = getModifierTranslations(localscore:GetModifiers()) - self:settextf("Mods: %s", m) + self:settextf("%s: %s", translations["ScoreModsUsed"], m) end end }, @@ -1612,7 +1673,7 @@ local function createList() if isLocal then if localrtTable == nil and GAMESTATE:GetCurrentSong() ~= nil then self:diffusealpha(1) - self:settext("No local scores recorded") + self:settext(translations["NoLocalScoresRecorded"]) else self:diffusealpha(0) self:settext("") @@ -1622,16 +1683,16 @@ local function createList() if scores == nil then self:diffusealpha(1) - self:settext("Chart is unranked") + self:settext(translations["ChartUnranked"]) elseif #scores == 0 and steps and fetchingScores[steps:GetChartKey()] == true then self:diffusealpha(1) - self:settext("Fetching scores...") + self:settext(translations["FetchingScores"]) elseif #scores == 0 and steps and fetchingScores[steps:GetChartKey()] == false then self:diffusealpha(1) - self:settext("No online scores recorded") + self:settext(translations["NoOnlineScoresRecorded"]) elseif isLocal and localscore == nil then self:diffusealpha(1) - self:settext("No local scores recorded") + self:settext(translations["NoLocalScoresRecorded"]) else self:diffusealpha(0) self:settext("") @@ -1719,10 +1780,10 @@ local function createList() -- preferably the defaults are the first position -- the inner lists have to be length 2 local choiceNames = { - {"Show Online", "Show Local"}, - {"Top Scores", "All Scores"}, - {"Hide Invalid", "Show Invalid"}, - {"Current Rate", "All Rates"}, + {translations["ShowOnlineScores"], translations["ShowLocalScores"]}, + {translations["ShowTopScores"], translations["ShowAllScores"]}, + {translations["HideInvalidScores"], translations["ShowInvalidScores"]}, + {translations["CurrentRateOnly"], translations["AllRates"]}, } -- this list defines how each choice finds its default choiceName index diff --git a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/tags.lua b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/tags.lua index 13746e0081..3db7b707ff 100644 --- a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/tags.lua +++ b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/generalPages/tags.lua @@ -68,6 +68,20 @@ do end end +local translations = { + AssignTag = THEME:GetString("ScreenSelectMusic Tags", "AssignTag"), + RequireTag = THEME:GetString("ScreenSelectMusic Tags", "RequireTag"), + HideTag = THEME:GetString("ScreenSelectMusic Tags", "HideTag"), + ModeALL = THEME:GetString("ScreenSelectMusic Tags", "ModeALL"), + ModeANY = THEME:GetString("ScreenSelectMusic Tags", "ModeANY"), + DeleteTag = THEME:GetString("ScreenSelectMusic Tags", "DeleteTag"), + TagDeleteInProgress = THEME:GetString("ScreenSelectMusic Tags", "TagDeleteInProgress"), + NewTag = THEME:GetString("ScreenSelectMusic Tags", "NewTag"), + NewTagQuestion = THEME:GetString("ScreenSelectMusic Tags", "NewTagQuestion"), + ApplyFilter = THEME:GetString("ScreenSelectMusic Tags", "ApplyFilter"), + ResetFilter = THEME:GetString("ScreenSelectMusic Tags", "ResetFilter"), +} + local tagTextSize = 1.2 local pageTextSize = 0.7 @@ -271,7 +285,7 @@ local function tagList() { -- Button to assign tags to charts Name = "assign", Type = "Exclusive", - Display = {"Assign"}, + Display = {translations["AssignTag"]}, IndexGetter = function() return 1 end, Condition = function() return true end, TapFunction = function() @@ -281,7 +295,7 @@ local function tagList() { -- Button to filter charts by tags (Require charts have these tags) Name = "filter", Type = "Exclusive", - Display = {"Require Tag"}, + Display = {translations["RequireTag"]}, IndexGetter = function() return 1 end, Condition = function() return true end, TapFunction = function() @@ -291,7 +305,7 @@ local function tagList() { -- Button to filter charts by tags (Hide charts with these tags) Name = "hide", Type = "Exclusive", - Display = {"Hide Tag"}, + Display = {translations["HideTag"]}, IndexGetter = function() return 1 end, Condition = function() return true end, TapFunction = function() @@ -301,7 +315,7 @@ local function tagList() { -- Button to change filter mode AND/OR Name = "filtermode", Type = "Toggle", - Display = {"Mode: AND", "Mode: OR"}, + Display = {translations["ModeALL"], translations["ModeANY"]}, IndexGetter = function() if tagListMode == "Require" then return WHEELDATA:GetRequiredTagMode() and 1 or 2 @@ -325,7 +339,7 @@ local function tagList() { -- Button to delete tags Name = "delete", Type = "Exclusive", - Display = {"Delete", "Deleting Tag"}, + Display = {translations["DeleteTag"], translations["TagDeleteInProgress"]}, IndexGetter = function() if tagListMode == "Delete" then return 2 @@ -345,7 +359,7 @@ local function tagList() { -- Button to create tags Name = "new", Type = "Tap", - Display = {"New"}, + Display = {translations["NewTag"]}, Condition = function() return true end, IndexGetter = function() return 1 end, TapFunction = function() @@ -363,7 +377,7 @@ local function tagList() off() -- input redirects are controlled here because we want to be careful not to break any prior redirects askForInputStringWithFunction( - "Enter New Tag Name", + translations["NewTagQuestion"], 128, false, function(answer) @@ -384,7 +398,7 @@ local function tagList() { -- Button to apply tag filter changes to music wheel Name = "apply", Type = "Tap", - Display = {"Apply"}, + Display = {translations["ApplyFilter"]}, Condition = function() return true end, IndexGetter = function() return 1 end, TapFunction = function() @@ -401,7 +415,7 @@ local function tagList() { -- Button to reset tag filters Name = "reset", Type = "Tap", - Display = {"Reset"}, + Display = {translations["ResetFilter"]}, Condition = function() return true end, IndexGetter = function() return 1 end, TapFunction = function() diff --git a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/wheel.lua b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/wheel.lua index 00cb0225be..792133a07c 100644 --- a/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/wheel.lua +++ b/Themes/Rebirth/BGAnimations/ScreenSelectMusic decorations/wheel.lua @@ -85,6 +85,16 @@ local actuals = { ScrollBarHeight = ratios.ScrollBarHeight * SCREEN_HEIGHT, } +local translations = { + NumberOfSongs = THEME:GetString("ScreenSelectMusic Wheel", "NumberOfSongs"), + AverageMSDShort = THEME:GetString("ScreenSelectMusic Wheel", "AverageMSDShort"), + AverageMSDLong = THEME:GetString("ScreenSelectMusic Wheel", "AverageMSDLong"), + PackClearedUsingDownrates = THEME:GetString("ScreenSelectMusic Wheel", "PackClearedUsingDownrates"), + SessionTime = THEME:GetString("ScreenSelectMusic Wheel", "SessionTime"), + SessionPlays = THEME:GetString("ScreenSelectMusic Wheel", "SessionPlays"), + AverageAccuracy = THEME:GetString("ScreenSelectMusic Wheel", "AverageAccuracy"), +} + local wheelItemTextSize = 0.62 local wheelItemGradeTextSize = 1 local wheelItemTitleTextSize = 0.82 @@ -276,7 +286,7 @@ local t = Def.ActorFrame { end end, OptionUpdatedMessageCommand = function(self, params) - if params and params.name == "Music Wheel Banners" then + if params and params.name == "Music Wheel Banners" or params.name == "Show Banners" then self:playcommand("UpdateWheelBanners") end end, @@ -448,7 +458,9 @@ local function songBannerSetter(self, song, isCurrentItem) if song then local bnpath = song:GetBannerPath() -- we load the fallback banner but for aesthetic purpose at the moment, invisible - if not bnpath then + if not showBanners() then + self:visible(false) + elseif not bnpath then bnpath = THEME:GetPathG("Common", "fallback banner") self:visible(false) else @@ -476,7 +488,9 @@ local function groupBannerSetter(self, group, isCurrentItem) local bnpath = WHEELDATA:GetFolderBanner(group) -- we load the fallback banner but for aesthetic purpose at the moment, invisible - if not bnpath or bnpath == "" then + if not showBanners() then + self:visible(false) + elseif not bnpath or bnpath == "" then bnpath = THEME:GetPathG("Common", "fallback banner") self:visible(false) else @@ -1003,7 +1017,7 @@ local function groupActorBuilder() end, UpdateTextCommand = function(self) self:visible(not WHEELDATA:inSortModeMenu()) - self:settextf("%d Songs (Avg %5.2f)", self.count, self.avg) + self:settextf("%d %s (%s %5.2f)", self.count, translations["NumberOfSongs"], translations["AverageMSDShort"], self.avg) end, SetPositionCommand = function(self) if getWheelPosition() then @@ -1057,7 +1071,7 @@ local function groupActorBuilder() lstr = THEME:GetString("Grade", self.lamp:sub(#"Grade_T")) self:diffuse(colorByGrade(self.lamp)) else - lstr = "Clear" + lstr = translations["PackClearedUsingDownrates"] -- color for a clear self:diffuse(colorByClearType("Clear")) end @@ -1483,7 +1497,9 @@ t[#t+1] = Def.ActorFrame { end, SetCommand = function(self) local bnpath = WHEELDATA:GetFolderBanner(openedGroup) - if not bnpath or bnpath == "" then + if not showBanners() then + self:visible(false) + elseif not bnpath or bnpath == "" then bnpath = THEME:GetPathG("Common", "fallback banner") self:visible(false) else @@ -1494,6 +1510,8 @@ t[#t+1] = Def.ActorFrame { OptionUpdatedMessageCommand = function(self, params) if params and params.name == "Video Banners" then self:SetDecodeMovie(useVideoBanners()) + elseif params and params.name == "Show Banners" then + self:playcommand("Set") end end, }, @@ -1524,7 +1542,7 @@ t[#t+1] = Def.ActorFrame { SetCommand = function(self) local files = WHEELDATA:GetFolderCount(openedGroup) local avg = WHEELDATA:GetFolderAverageDifficulty(openedGroup)[1] - self:settextf("%d Songs (Average MSD: %5.2f)", files, avg) + self:settextf("%d %s (%s: %5.2f)", files, translations["NumberOfSongs"], translations["AverageMSDLong"], avg) end } }, @@ -1563,7 +1581,7 @@ t[#t+1] = Def.ActorFrame { end, SetCommand = function(self) local sesstime = GAMESTATE:GetSessionTime() - self:settextf("Session Time: %s", SecondsToHHMMSS(sesstime)) + self:settextf("%s: %s", translations["SessionTime"], SecondsToHHMMSS(sesstime)) end }, LoadFont("Common Normal") .. { @@ -1577,7 +1595,7 @@ t[#t+1] = Def.ActorFrame { registerActorToColorConfigElement(self, "main", "PrimaryText") end, SetCommand = function(self) - self:settextf("Session Plays: %d", playsThisSession) + self:settextf("%s: %d", translations["SessionPlays"], playsThisSession) end }, LoadFont("Common Normal") .. { @@ -1591,7 +1609,7 @@ t[#t+1] = Def.ActorFrame { registerActorToColorConfigElement(self, "main", "PrimaryText") end, SetCommand = function(self) - self:settextf("Average Accuracy: %5.2f%%", accThisSession) + self:settextf("%s: %5.2f%%", translations["AverageAccuracy"], accThisSession) end }, Def.ActorFrame { diff --git a/Themes/Rebirth/BGAnimations/ScreenSelectMusic underlay/default.lua b/Themes/Rebirth/BGAnimations/ScreenSelectMusic underlay/default.lua index fcf9855c38..23c379251c 100644 --- a/Themes/Rebirth/BGAnimations/ScreenSelectMusic underlay/default.lua +++ b/Themes/Rebirth/BGAnimations/ScreenSelectMusic underlay/default.lua @@ -1,4 +1,4 @@ -local showbg = function() return themeConfig:get_data().global.ShowBackgrounds end +local showbg = function() return PREFSMAN:GetPreference("ShowBackgrounds") end local avgcolorbg = function() return themeConfig:get_data().global.FallbackToAverageColorBG end local t = Def.ActorFrame { Name = "UnderlayFile", diff --git a/Themes/Rebirth/BGAnimations/ScreenSelectProfile overlay.lua b/Themes/Rebirth/BGAnimations/ScreenSelectProfile overlay.lua deleted file mode 100644 index 2089f3ed59..0000000000 --- a/Themes/Rebirth/BGAnimations/ScreenSelectProfile overlay.lua +++ /dev/null @@ -1,197 +0,0 @@ -local translated_info = { - Title = "Select Profile", - SongPlayed = "Song Played", - SongsPlayed = "Songs Played", - NoProfile = "No Profile", - PressStart = "Press Start" -} - -function GetLocalProfiles() - local t = {} - - for p = 0, PROFILEMAN:GetNumLocalProfiles() - 1 do - local profileID = PROFILEMAN:GetLocalProfileIDFromIndex(p) - local profile = PROFILEMAN:GetLocalProfileFromIndex(p) - local ProfileCard = - Def.ActorFrame { - Name = p, - LoadFont("Common Large") .. - { - Text = string.format("%s: %.2f", profile:GetDisplayName(), profile:GetPlayerRating()), - InitCommand = function(self) - self:y(-10):zoom(0.4):ztest(true, maxwidth, (200 - 34 - 4) / 0.4) - end - }, - LoadFont("Common Normal") .. - { - InitCommand = function(self) - self:y(8):zoom(0.5):vertspacing(-8):ztest(true):maxwidth((200 - 34 - 4) / 0.5) - end, - BeginCommand = function(self) - local numSongsPlayed = profile:GetNumTotalSongsPlayed() - local s = numSongsPlayed == 1 and translated_info["SongPlayed"] or translated_info["SongsPlayed"] - self:settext(numSongsPlayed .. " " .. s) - end - } - } - t[#t + 1] = ProfileCard - end - - return t -end - -function LoadPlayerStuff(Player) - local t = {} - t[#t + 1] = - Def.ActorFrame { - Name = "SmallFrame", - InitCommand = function(self) - self:y(-2) - end, - Def.Quad { - InitCommand = function(self) - self:zoomto(200, 40 + 2) - end, - OnCommand = function(self) - self:diffusealpha(0.3) - end - } - } - - t[#t + 1] = - Def.ActorScroller { - Name = "Scroller", - NumItemsToDraw = 6, - OnCommand = function(self) - self:y(1):SetFastCatchup(true):SetMask(200, 58):SetSecondsPerItem(0.15) - end, - TransformFunction = function(self, offset, itemIndex, numItems) - local focus = scale(math.abs(offset), 0, 2, 1, 0) - self:visible(false) - self:y(math.floor(offset * 40)) - end, - children = GetLocalProfiles() - } - - return t -end - -function UpdateInternal3(self, Player) - local pn = (Player == PLAYER_1) and 1 - local frame = self:GetChild(string.format("P%uFrame", pn)) - local scroller = frame:GetChild("Scroller") - local smallframe = frame:GetChild("SmallFrame") - - if GAMESTATE:IsHumanPlayer() then - frame:visible(true) - smallframe:visible(true) - scroller:visible(true) - local ind = SCREENMAN:GetTopScreen():GetProfileIndex(Player) - if ind > 0 then - scroller:SetDestinationItem(ind - 1) - else - if SCREENMAN:GetTopScreen():SetProfileIndex(Player, 1) then - scroller:SetDestinationItem(0) - self:queuecommand("UpdateInternal2") - else - smallframe:visible(false) - scroller:visible(false) - end - end - else - scroller:visible(false) - smallframe:visible(false) - end -end - -local theThingVeryImportant -local startSound - -local function input(event) - if event.type == "InputEventType_FirstPress" then - if event.button == "Back" then - SCREENMAN:GetTopScreen():Cancel() - elseif event.button == "Start" then - startSound:queuecommand("StartButton") - elseif event.button == "Down" or event.button == "MenuDown" then - local ind = SCREENMAN:GetTopScreen():GetProfileIndex(PLAYER_1) - if ind > 0 then - if SCREENMAN:GetTopScreen():SetProfileIndex(PLAYER_1, ind + 1) then - MESSAGEMAN:Broadcast("DirectionButton") - theThingVeryImportant:queuecommand("UpdateInternal2") - end - end - elseif event.button == "Up" or event.button == "MenuUp" then - local ind = SCREENMAN:GetTopScreen():GetProfileIndex(PLAYER_1) - if ind > 1 then - if SCREENMAN:GetTopScreen():SetProfileIndex(PLAYER_1, ind - 1) then - MESSAGEMAN:Broadcast("DirectionButton") - theThingVeryImportant:queuecommand("UpdateInternal2") - end - end - end - end - return false -end - -local t = Def.ActorFrame {} - -t[#t + 1] = - Def.ActorFrame { - InitCommand = function(self) - theThingVeryImportant = self - end, - OnCommand = function(self) - SCREENMAN:GetTopScreen():SetProfileIndex(PLAYER_1, 0) - end, - OnCommand = function(self, params) - self:queuecommand("UpdateInternal2") - end, - UpdateInternal2Command = function(self) - UpdateInternal3(self, PLAYER_1) - end, - children = { - Def.ActorFrame { - Name = "P1Frame", - InitCommand = function(self) - self:x(SCREEN_CENTER_X):y(SCREEN_CENTER_Y) - end, - OnCommand = function(self) - SCREENMAN:GetTopScreen():AddInputCallback(input) - self:zoom(0):bounceend(0.2):zoom(1) - end, - OffCommand = function(self) - self:bouncebegin(0.2):zoom(0) - end, - PlayerJoinedMessageCommand = function(self, param) - if param.Player == PLAYER_1 then - self:zoom(1.15):bounceend(0.175):zoom(1.0) - end - end, - children = LoadPlayerStuff(PLAYER_1) - }, - -- sounds - LoadActor(THEME:GetPathS("Common", "start")) .. - { - InitCommand = function(self) - startSound = self - end, - StartButtonCommand = function(self) - self:play() - self:sleep(0.2) - self:queuecommand("Done") - end, - DoneCommand = function(self) - SCREENMAN:GetTopScreen():Finish() - end - }, - LoadActor(THEME:GetPathS("Common", "value")) .. - { - DirectionButtonMessageCommand = function(self) - self:play() - end - } - } -} - -return t diff --git a/Themes/Rebirth/BGAnimations/ScreenTextEntry underlay.lua b/Themes/Rebirth/BGAnimations/ScreenTextEntry underlay.lua index 60eb7c7d65..e0caf4abd0 100644 --- a/Themes/Rebirth/BGAnimations/ScreenTextEntry underlay.lua +++ b/Themes/Rebirth/BGAnimations/ScreenTextEntry underlay.lua @@ -10,6 +10,11 @@ local INFORMATIONBOXHEIGHT = 50 / 1080 * SCREEN_HEIGHT local exitwidth = 70 / 1920 * SCREEN_WIDTH local exitheight = 50 / 1080 * SCREEN_HEIGHT +local translations = { + Information = THEME:GetString("ScreenTextEntry", "Information"), + Exit = THEME:GetString("ScreenTextEntry", "Exit"), +} + local dimAlpha = 0.6 local boxAlpha = 0.5 local hoverAlpha = 0.6 @@ -90,7 +95,8 @@ return Def.ActorFrame { end, PressyMyMouseButtonCommand = function(self) if isOver(self) then - SCREENMAN:GetTopScreen():Cancel() + -- true means cancelled, so the input is rejected + SCREENMAN:GetTopScreen():End(true) end end, HighlightyMyMouseHoveringCommand = function(self) @@ -108,7 +114,7 @@ return Def.ActorFrame { self:xy(-boxWidth/2 + sideMargin, -boxHeight/2 + INFORMATIONupperGap) self:zoom(INFORMATIONtextsize) self:maxwidth(boxWidth / INFORMATIONtextsize) - self:settext("Information") + self:settext(translations["Information"]) end }, LoadFont("Common Normal") .. { @@ -117,7 +123,7 @@ return Def.ActorFrame { self:zoom(exittextsize) self:maxwidth(60 / 1920 * SCREEN_WIDTH / exittextsize) self:xy(boxWidth/2 - sideMargin - exitwidth/2, boxHeight/2 - bottomMargin - exitheight/1.7) - self:settext("Exit") + self:settext(translations["Exit"]) end } } diff --git a/Themes/Rebirth/BGAnimations/ScreenTitleMenu overlay/profileSelect.lua b/Themes/Rebirth/BGAnimations/ScreenTitleMenu overlay/profileSelect.lua index 601f364c9b..8607713f10 100644 --- a/Themes/Rebirth/BGAnimations/ScreenTitleMenu overlay/profileSelect.lua +++ b/Themes/Rebirth/BGAnimations/ScreenTitleMenu overlay/profileSelect.lua @@ -59,6 +59,18 @@ local actuals = { OfflineUpperGap = ratios.OfflineUpperGap * SCREEN_HEIGHT, } +local translations = { + Plays = THEME:GetString("ScreenTitleMenu", "Plays"), + ArrowsSmashed = THEME:GetString("ScreenTitleMenu", "ArrowsSmashed"), + Playtime = THEME:GetString("ScreenTitleMenu", "Playtime"), + PlayerRatings = THEME:GetString("ScreenTitleMenu", "PlayerRatings"), + OnlineRating = THEME:GetString("ScreenTitleMenu", "OnlineRating"), + OfflineRating = THEME:GetString("ScreenTitleMenu", "OfflineRating"), + MakeFirstProfileQuestion = THEME:GetString("ScreenTitleMenu", "MakeFirstProfileQuestion"), + MakeProfileError = THEME:GetString("ScreenTitleMenu", "MakeProfileError"), + SelectProfile = THEME:GetString("ScreenTitleMenu", "SelectProfile"), +} + local profileIDs = PROFILEMAN:GetLocalProfileIDs() local renameNewProfile = false local focused = false @@ -355,7 +367,7 @@ local function generateItems() SetCommand = function(self) if profile then local scores = profile:GetTotalNumSongsPlayed() - self:settextf("%d plays", scores) + self:settextf("%d %s", scores, translations["Plays"]) end end }, @@ -373,7 +385,7 @@ local function generateItems() SetCommand = function(self) if profile then local taps = profile:GetTotalTapsAndHolds() - self:settextf("%d arrows smashed", taps) + self:settextf("%d %s", taps, translations["ArrowsSmashed"]) end end }, @@ -391,7 +403,7 @@ local function generateItems() SetCommand = function(self) if profile then local secs = profile:GetTotalSessionSeconds() - self:settextf("%s playtime", SecondsToHHMMSS(secs)) + self:settextf("%s %s", SecondsToHHMMSS(secs), translations["Playtime"]) end end } @@ -409,7 +421,7 @@ local function generateItems() self:valign(0):halign(0) self:zoom(playerRatingsTextSize) self:maxwidth((actuals.Width - actuals.RatingLeftGap) / playerRatingsTextSize - textzoomFudge) - self:settext("Player Ratings:") + self:settextf("%s:", translations["PlayerRatings"]) self:diffuse(primaryTextColor) self:diffusealpha(1) end @@ -426,7 +438,7 @@ local function generateItems() self:diffusealpha(1) end, SetCommand = function(self) - self:settext("Online - 00.00") + self:settextf("%s - 00.00", translations["OnlineRating"]) end },]] LoadFont("Common Normal") .. { @@ -442,7 +454,7 @@ local function generateItems() SetCommand = function(self) if profile then local rating = profile:GetPlayerRating() - self:settextf("Offline - %5.2f", rating) + self:settextf("%s - %5.2f", translations["OfflineRating"], rating) end end } @@ -483,13 +495,47 @@ local function generateItems() end) end, FirstUpdateCommand = function(self) + -- waiting for the crashdump upload dialog to go away + if renameNewProfile then + if PREFSMAN:GetPreference("ShowMinidumpUploadDialogue") then + self:sleep(0.2):queuecommand("Keepwastingtimestart") + else + self:playcommand("Finishwastingtime") + end + end + end, + KeepwastingtimestartCommand = function(self) + -- looping to wait for the dialog to go away + if renameNewProfile then + if PREFSMAN:GetPreference("ShowMinidumpUploadDialogue") then + self:sleep(0.2):queuecommand("Keepwastingtimestart") + else + self:playcommand("Finishwastingtime") + end + end + end, + FinishwastingtimeCommand = function(self) if renameNewProfile then local profile = PROFILEMAN:GetLocalProfile(profileIDs[1]) + local redir = SCREENMAN:get_input_redirected(PLAYER_1) + local function off() + if redir then + SCREENMAN:set_input_redirected(PLAYER_1, false) + end + end + local function on() + if redir then + SCREENMAN:set_input_redirected(PLAYER_1, true) + end + end + off() + local function f(answer) profile:RenameProfile(answer) self:playcommand("ProfileRenamed") + on() end - local question = "No Profiles detected! A new one was made for you.\nPlease enter a new profile name." + local question = translations["MakeFirstProfileQuestion"] askForInputStringWithFunction( question, 64, @@ -498,7 +544,7 @@ local function generateItems() function(answer) local result = answer ~= nil and answer:gsub("^%s*(.-)%s*$", "%1") ~= "" and not answer:match("::") and answer:gsub("^%s*(.-)%s*$", "%1"):sub(-1) ~= ":" if not result then - SCREENMAN:GetTopScreen():GetChild("Question"):settext(question .. "\nDo not leave this space blank. Do not use ':'") + SCREENMAN:GetTopScreen():GetChild("Question"):settext(question .. "\n" .. translations["MakeProfileError"]) end return result, "Response invalid." end, @@ -506,6 +552,7 @@ local function generateItems() -- do nothing -- the profile name is Default Profile -- cringe name tbh + on() end ) end @@ -580,7 +627,7 @@ local function generateItems() self:halign(1) self:xy(actuals.Width, -actuals.FrameUpperGap/2) self:zoom(0.5) - self:settext("Select a Profile") + self:settext(translations["SelectProfile"]) self:diffusealpha(0) end, FocusChangeCommand = function(self) diff --git a/Themes/Rebirth/BGAnimations/ScreenTitleMenu underlay.lua b/Themes/Rebirth/BGAnimations/ScreenTitleMenu underlay.lua index 0c594817e1..7157ce86d6 100644 --- a/Themes/Rebirth/BGAnimations/ScreenTitleMenu underlay.lua +++ b/Themes/Rebirth/BGAnimations/ScreenTitleMenu underlay.lua @@ -31,6 +31,12 @@ local versionNumberLeftGap = 5 / 1920 * SCREEN_WIDTH local versionNumberUpperGap = 980 / 1080 * SCREEN_HEIGHT local themeVersionUpperGap = 1015 / 1080 * SCREEN_HEIGHT +local translations = { + GameName = THEME:GetString("Common", "Etterna"):upper(), + UpdateAvailable = THEME:GetString("ScreenTitleMenu", "UpdateAvailable"), + By = THEME:GetString("ScreenTitleMenu", "By"), +} + local nameTextSize = 0.9 local themenameTextSize = 0.8 local versionTextSize = 0.5 @@ -181,7 +187,7 @@ t[#t+1] = Def.ActorFrame { self:x(logoNameLeftGap + logoW) self:zoom(nameTextSize) self:maxwidth((separatorxpos - (logoNameLeftGap + logoW) - logoNameLeftGap) / nameTextSize) - self:settext("ETTERNA") + self:settext(translations["GameName"]) self:diffuse(COLORS:getTitleColor("PrimaryText")) self:diffusealpha(1) end @@ -218,7 +224,7 @@ t[#t+1] = Def.ActorFrame { self:xy(vnc:GetX() + vnc:GetZoomedWidth() + bufferspace, versionNumberUpperGap) self:zoom(versionTextSize) self:maxwidth(((gradientwidth - vnc:GetX() - vnc:GetZoomedWidth() - logoFrameLeftGap - separatorthickness) / versionTextSize)) - self:settextf("- Update Available (%s)", DLMAN:GetLastVersion()) + self:settextf("- %s (%s)", translations["UpdateAvailable"], DLMAN:GetLastVersion()) self:diffuse(COLORS:getTitleColor("UpdateText")) self:diffusealpha(1) self:visible(false) @@ -259,7 +265,7 @@ t[#t+1] = Def.ActorFrame { self:xy(versionNumberLeftGap, themeVersionUpperGap) self:maxwidth((gradientwidth - versionNumberLeftGap - logoFrameLeftGap - separatorthickness) / versionTextSizeSmall) self:zoom(versionTextSizeSmall) - self:settext("("..getThemeName().." v"..getThemeVersion().."@"..getThemeDate().." by "..getThemeAuthor()..")") + self:settext("("..getThemeName().." v"..getThemeVersion().."@"..getThemeDate().." " .. translations["By"] .. " "..getThemeAuthor()..")") self:diffuse(COLORS:getTitleColor("SecondaryText")) self:diffusealpha(1) end diff --git a/Themes/Rebirth/BGAnimations/chordDensityGraph.lua b/Themes/Rebirth/BGAnimations/chordDensityGraph.lua index 223874a094..3ec7ef1663 100644 --- a/Themes/Rebirth/BGAnimations/chordDensityGraph.lua +++ b/Themes/Rebirth/BGAnimations/chordDensityGraph.lua @@ -13,6 +13,12 @@ if sizing == nil then sizing = {} end local stepsinuse = nil local lowDensityColor = COLORS:getColor("chartPreview", "GraphLowestDensityBar") local highDensityColor = COLORS:getColor("chartPreview", "GraphHighestDensityBar") + +local translations = { + NPS = THEME:GetString("ChordDensityGraph", "NPS"), + BPM = THEME:GetString("ChordDensityGraph", "BPM"), +} + local t = Def.ActorFrame { Name = "ChordDensityGraphFile", InitCommand = function(self) @@ -85,7 +91,7 @@ local t = Def.ActorFrame { local hoveredNPS = self.npsVector[hoveredIndex] local td = stepsinuse:GetTimingData() local bpm = td:GetBPMAtBeat(td:GetBeatFromElapsedTime(dist * r)) * r - stro = string.format("%s\n%d NPS\n%d BPM", postext, hoveredNPS, bpm) + stro = string.format("%s\n%d %s\n%d %s", postext, hoveredNPS, translations["NPS"], bpm, translations["BPM"]) end TOOLTIP:SetText(stro) TOOLTIP:Show() @@ -150,7 +156,7 @@ local function updateGraphMultiVertex(parent, self, steps) end end - txt:settext(heightScale / 2 * 0.7 .. "NPS") + txt:settext(heightScale / 2 * 0.7 .. translations["NPS"]) heightScale = sizing.Height / heightScale local verts = {} -- reset the vertices for the graph diff --git a/Themes/Rebirth/BGAnimations/judgmentBars.lua b/Themes/Rebirth/BGAnimations/judgmentBars.lua index 5439e835eb..4adeea0a6b 100644 --- a/Themes/Rebirth/BGAnimations/judgmentBars.lua +++ b/Themes/Rebirth/BGAnimations/judgmentBars.lua @@ -49,6 +49,12 @@ local function makeJudgment(i) self:y((((i-1) * sizing.JudgmentBarHeight + (i-1) * sizing.JudgmentBarSpacing) / sizing.JudgmentBarAllottedSpace) * sizing.JudgmentBarAllottedSpace) end, SetCommand = function(self, params) + if params.usingCustomWindows then + local lastSnapshot = REPLAYS:GetActiveReplay():GetLastReplaySnapshot() + count = lastSnapshot:GetJudgments()[jdg:gsub("TapNoteScore_", "")] + return + end + if params.score ~= nil then if params.judgeSetting ~= nil and params.score:HasReplayData() then count = getRescoredJudge(params.score:GetOffsetVector(), params.judgeSetting, i) @@ -99,6 +105,13 @@ local function makeJudgment(i) self:maxwidth((sizing.JudgmentBarLength - sizing.JudgmentNameLeftGap - sizing.JudgmentCountRightGap - judgmentCountPercentBump) / 4 * 3 / judgmentTextZoom) self:settext(getJudgeStrings(ms.JudgeCount[i])) registerActorToColorConfigElement(self, "judgment", "TextOverBars") + end, + SetCommand = function(self, params) + if params and params.usingCustomWindows then + self:settext(getCustomWindowConfigJudgmentName(jdg)) + else + self:settext(getJudgeStrings(ms.JudgeCount[i])) + end end }, Def.RollingNumbers { diff --git a/Themes/Rebirth/BGAnimations/offsetplot.lua b/Themes/Rebirth/BGAnimations/offsetplot.lua index f85f219db9..217ac7e372 100644 --- a/Themes/Rebirth/BGAnimations/offsetplot.lua +++ b/Themes/Rebirth/BGAnimations/offsetplot.lua @@ -11,8 +11,21 @@ if extraFeatures == nil then extraFeatures = false end -- all elements are placed relative to default valign - 0 halign -- this means relatively to center vertically and relative to the left end horizontally +local translations = { + StandardDeviation = THEME:GetString("OffsetPlot", "StandardDeviation"), + Mean = THEME:GetString("OffsetPlot", "Mean"), + Time = THEME:GetString("OffsetPlot", "Time"), + Milliseconds = THEME:GetString("OffsetPlot", "Milliseconds"), + Late = THEME:GetString("OffsetPlot", "Late"), + Early = THEME:GetString("OffsetPlot", "Early"), + Instructions = THEME:GetString("OffsetPlot", "Instructions"), + CurrentColumnHighlights = THEME:GetString("OffsetPlot", "CurrentColumnHighlights"), + OffsetWarning = THEME:GetString("OffsetPlot", "UsingReprioritized"), +} + local judgeSetting = (PREFSMAN:GetPreference("SortBySSRNormPercent") and 4 or GetTimingDifficulty()) local timingScale = ms.JudgeScalers[judgeSetting] +local usingCustomWindows = false -- cap the graph to this local maxOffset = 180 @@ -195,7 +208,7 @@ local t = Def.ActorFrame { if isOver(bg) then local top = SCREENMAN:GetTopScreen() -- dont break if it will break (we can only do this from the eval screen) - if not top.GetReplaySnapshotJudgmentsForNoterow or not top.GetReplaySnapshotWifePercentForNoterow then + if not top.RescoreReplay then return end @@ -208,32 +221,34 @@ local t = Def.ActorFrame { local lastsec = GAMESTATE:GetCurrentSteps():GetLastSecond() local row = td:GetBeatFromElapsedTime(percent * lastsec) * 48 - local judgments = top:GetReplaySnapshotJudgmentsForNoterow(row) - local wifescore = top:GetReplaySnapshotWifePercentForNoterow(row) * 100 + local replay = REPLAYS:GetActiveReplay() + local snapshot = replay:GetReplaySnapshotForNoterow(row) + local judgments = snapshot:GetJudgments() + local wifescore = snapshot:GetWifePercent() * 100 local time = SecondsToHHMMSS(td:GetElapsedTimeFromNoteRow(row)) - local mean = top:GetReplaySnapshotMeanForNoterow(row) - local sd = top:GetReplaySnapshotSDForNoterow(row) + local mean = snapshot:GetMean() + local sd = snapshot:GetStandardDeviation() - local marvCount = judgments[10] - local perfCount = judgments[9] - local greatCount = judgments[8] - local goodCount = judgments[7] - local badCount = judgments[6] - local missCount = judgments[5] + local marvCount = judgments["W1"] + local perfCount = judgments["W2"] + local greatCount = judgments["W3"] + local goodCount = judgments["W4"] + local badCount = judgments["W5"] + local missCount = judgments["Miss"] -- excessively long string format for translation support local txt = string.format( - "%5.6f%%\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %0.2fms\n%s: %0.2fms\n%s: %s", + "%5.6f%%\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %0.2f%s\n%s: %0.2f%s\n%s: %s", wifescore, - "Marvelous", marvCount, - "Perfect", perfCount, - "Great", greatCount, - "Good", goodCount, - "Bad", badCount, - "Miss", missCount, - "Std. Dev", sd, - "Mean", mean, - "Time", time + getJudgeStrings("TapNoteScore_W1"), marvCount, + getJudgeStrings("TapNoteScore_W2"), perfCount, + getJudgeStrings("TapNoteScore_W3"), greatCount, + getJudgeStrings("TapNoteScore_W4"), goodCount, + getJudgeStrings("TapNoteScore_W5"), badCount, + getJudgeStrings("TapNoteScore_Miss"), missCount, + translations["StandardDeviation"], sd, translations["Milliseconds"], + translations["Mean"], mean, translations["Milliseconds"], + translations["Time"], time ) local mp = self:GetChild("MousePosition") @@ -346,6 +361,7 @@ for i, j in ipairs(barJudgments) do self:finishtweening() self:smooth(resizeAnimationSeconds) local window = ms.getLowerWindowForJudgment(j, timingScale) + if usingCustomWindows then window = getCustomWindowConfigJudgmentWindowLowerBound(j) end self:y(fitY(window, maxOffset)) self:zoomto(sizing.Width, lineThickness) end @@ -363,6 +379,7 @@ for i, j in ipairs(barJudgments) do self:finishtweening() self:smooth(resizeAnimationSeconds) local window = ms.getLowerWindowForJudgment(j, timingScale) + if usingCustomWindows then window = getCustomWindowConfigJudgmentWindowLowerBound(j) end self:y(fitY(-window, maxOffset)) self:zoomto(sizing.Width, lineThickness) end @@ -383,7 +400,7 @@ t[#t+1] = LoadFont("Common Normal") .. { self:smooth(resizeAnimationSeconds) local bound = ms.getUpperWindowForJudgment(barJudgments[#barJudgments], timingScale) self:xy(textPadding, textPadding) - self:settextf("Late (+%dms)", bound) + self:settextf("%s (+%d%s)", translations["Late"], bound, translations["Milliseconds"]) end } @@ -401,7 +418,7 @@ t[#t+1] = LoadFont("Common Normal") .. { self:smooth(resizeAnimationSeconds) local bound = ms.getUpperWindowForJudgment(barJudgments[#barJudgments], timingScale) self:xy(textPadding, sizing.Height - textPadding) - self:settextf("Early (-%dms)", bound) + self:settextf("%s (-%d%s)", translations["Early"], bound, translations["Milliseconds"]) end } @@ -432,11 +449,31 @@ t[#t+1] = LoadFont("Common Normal") .. { end cols[#cols] = nil cols = table.concat(cols) - self:settextf("Up/Down for column highlights (Now: %s)", cols) + self:settextf("%s (%s: %s)", translations["Instructions"], translations["CurrentColumnHighlights"], cols) end end } +t[#t+1] = LoadFont("Common Normal") .. { + Name = "OffsetWarningText", + InitCommand = function(self) + self:valign(0) + self:zoom(instructionTextSize) + self:settext(translations["OffsetWarning"]) + registerActorToColorConfigElement(self, "offsetPlot", "Text") + self:playcommand("UpdateSizing") + self:finishtweening() + end, + UpdateSizingCommand = function(self) + self:visible(usingCustomWindows and currentCustomWindowConfigUsesOldestNoteFirst()) + + self:finishtweening() + self:smooth(resizeAnimationSeconds) + self:xy(sizing.Width / 2, textPadding) + self:maxwidth((sizing.Width - self:GetParent():GetChild("LateText"):GetZoomedWidth() * 2) / instructionTextSize - textPadding) + end, +} + -- keeping track of stuff for persistence dont look at this local lastOffsets = {} local lastTracks = {} @@ -462,6 +499,8 @@ t[#t+1] = Def.ActorMultiVertex { self:queuecommand("DrawOffsets") end, LoadOffsetsCommand = function(self, params) + usingCustomWindows = params.usingCustomWindows or false + -- makes sure all sizes are updated self:GetParent():playcommand("UpdateSizing", params) @@ -520,6 +559,9 @@ t[#t+1] = Def.ActorMultiVertex { if types[i] ~= "TapNoteType_Mine" then -- handle highlighting logic local dotColor = colorByTapOffset(offset, timingScale) + if usingCustomWindows then + dotColor = colorByTapOffsetCustomWindow(offset, getCurrentCustomWindowConfigJudgmentWindowTable()) + end if not columnIsHighlighted(column) then dotColor[4] = unHighlightedAlpha end diff --git a/Themes/Rebirth/BGAnimations/playerInfoFrame/assetsettings.lua b/Themes/Rebirth/BGAnimations/playerInfoFrame/assetsettings.lua index 22e814aafe..98de1f5178 100644 --- a/Themes/Rebirth/BGAnimations/playerInfoFrame/assetsettings.lua +++ b/Themes/Rebirth/BGAnimations/playerInfoFrame/assetsettings.lua @@ -25,6 +25,15 @@ local animationSeconds = 0.1 local focused = false local prevScreen = "" +local translations = { + Title = THEME:GetString("AssetSettings", "Title"), + HoveredItem = THEME:GetString("AssetSettings", "HoveredItem"), + SelectedItem = THEME:GetString("AssetSettings", "SelectedItem"), + ToastyPageDisplay = THEME:GetString("AssetSettings", "ToastyPageDisplay"), + AvatarPageDisplay = THEME:GetString("AssetSettings", "AvatarPageDisplay"), + JudgmentPageDisplay = THEME:GetString("AssetSettings", "JudgmentPageDisplay"), +} + local t = Def.ActorFrame { Name = "AssetSettingsFile", InitCommand = function(self) @@ -119,7 +128,7 @@ t[#t+1] = LoadFont("Common Normal") .. { self:xy(actuals.EdgePadding, actuals.TopLipHeight / 2) self:zoom(titleTextSize) self:maxwidth(actuals.Width / titleTextSize - textZoomFudge) - self:settext("Asset Settings") + self:settext(translations["Title"]) registerActorToColorConfigElement(self, "main", "PrimaryText") end } @@ -498,7 +507,7 @@ local function assetList() if type ~= nil then out = type:gsub("^%l", string.upper) end - self:settextf("Hovered: %s", out) + self:settextf("%s: %s", translations["HoveredItem"], out) end, CursorMovedMessageCommand = function(self) self:queuecommand("Set") @@ -523,7 +532,7 @@ local function assetList() if type ~= nil then out = type:gsub("^%l", string.upper) end - self:settextf("Selected: %s", out) + self:settextf("%s: %s", translations["SelectedItem"], out) end, PickChangedMessageCommand = function(self) self:queuecommand("Set") @@ -761,7 +770,7 @@ local function assetList() { -- Set to Toasty Select Page Name = "toasty", Type = "Exclusive", - Display = {"Toasty"}, + Display = {translations["ToastyPageDisplay"]}, IndexGetter = function() return 1 end, Condition = function() return true end, TapFunction = function() @@ -772,7 +781,7 @@ local function assetList() { -- Set to Avatar Select Page Name = "avatar", Type = "Exclusive", - Display = {"Avatar"}, + Display = {translations["AvatarPageDisplay"]}, IndexGetter = function() return 1 end, Condition = function() return true end, TapFunction = function() @@ -783,7 +792,7 @@ local function assetList() { -- Set to Judgment Select Page Name = "judgment", Type = "Exclusive", - Display = {"Judgment"}, + Display = {translations["JudgmentPageDisplay"]}, IndexGetter = function() return 1 end, Condition = function() return true end, TapFunction = function() diff --git a/Themes/Rebirth/BGAnimations/playerInfoFrame/downloads.lua b/Themes/Rebirth/BGAnimations/playerInfoFrame/downloads.lua index 7dc6f415eb..ef4222c14f 100644 --- a/Themes/Rebirth/BGAnimations/playerInfoFrame/downloads.lua +++ b/Themes/Rebirth/BGAnimations/playerInfoFrame/downloads.lua @@ -58,6 +58,31 @@ local hiddenframeX = SCREEN_WIDTH local animationSeconds = 0.1 local focused = false +local translations = { + Title = THEME:GetString("PackDownloader", "Title"), + Back = THEME:GetString("PackDownloader", "Back"), + BundleSelect = THEME:GetString("PackDownloader", "BundleSelect"), + CancelAll = THEME:GetString("PackDownloader", "CancelAll"), + Expanded = THEME:GetString("PackDownloader", "Expanded"), + Novice = THEME:GetString("PackDownloader", "Novice"), + Beginner = THEME:GetString("PackDownloader", "Beginner"), + Intermediate = THEME:GetString("PackDownloader", "Intermediate"), + Advanced = THEME:GetString("PackDownloader", "Advanced"), + Expert = THEME:GetString("PackDownloader", "Expert"), + Megabytes = THEME:GetString("PackDownloader", "Megabytes"), + Cancel = THEME:GetString("PackDownloader", "Cancel"), + Queued = THEME:GetString("PackDownloader", "Queued"), + HeaderName = THEME:GetString("PackDownloader", "HeaderName"), + HeaderAverage = THEME:GetString("PackDownloader", "HeaderAverage"), + HeaderSize = THEME:GetString("PackDownloader", "HeaderSize"), + DownloadBundle = THEME:GetString("PackDownloader", "DownloadBundle"), + DownloadBundleMirrored = THEME:GetString("PackDownloader", "DownloadBundleMirrored"), + DownloadPack = THEME:GetString("PackDownloader", "DownloadPack"), + DownloadPackMirrored = THEME:GetString("PackDownloader", "DownloadPackMirrored"), + AlreadyInstalled = THEME:GetString("PackDownloader", "AlreadyInstalled"), + CurrentlyDownloading = THEME:GetString("PackDownloader", "CurrentlyDownloading"), +} + local t = Def.ActorFrame { Name = "DownloadsFile", InitCommand = function(self) @@ -161,7 +186,7 @@ t[#t+1] = LoadFont("Common Normal") .. { self:xy(actuals.EdgePadding, actuals.TopLipHeight / 2) self:zoom(titleTextSize) self:maxwidth(actuals.Width / titleTextSize - textZoomFudge) - self:settext("Pack Downloader") + self:settext(translations["Title"]) registerActorToColorConfigElement(self, "main", "PrimaryText") end } @@ -237,7 +262,7 @@ local function downloadsList() { -- Enter or Exit from Bundle Select Name = "bundleselect", Type = "Tap", - Display = {"Bundle Select", "Back"}, + Display = {translations["BundleSelect"], translations["Back"]}, IndexGetter = function() if inBundles then return 2 @@ -254,7 +279,7 @@ local function downloadsList() { -- Cancel all current downloads Name = "cancelall", Type = "Tap", - Display = {"Cancel All Downloads"}, + Display = {translations["CancelAll"]}, IndexGetter = function() return 1 end, Condition = function() return true end, TapFunction = function() @@ -442,8 +467,8 @@ local function downloadsList() if pack ~= nil then self:settext(pack:GetName()) elseif bundle ~= nil then - local expanded = i % 2 == 0 and " Expanded" or "" - self:settext(bundleTypes[index] .. expanded) + local expanded = i % 2 == 0 and " "..translations["Expanded"] or "" + self:settext(translations[bundleTypes[index]] .. expanded) end self:alphaDeterminingFunction() end, @@ -494,11 +519,11 @@ local function downloadsList() SetPackCommand = function(self) if pack ~= nil then local sz = pack:GetSize() / 1024 / 1024 - self:settextf("%iMB", sz) + self:settextf("%i%s", sz, translations["Megabytes"]) self:diffuse(colorByFileSize(sz)) elseif bundle ~= nil then local sz = bundle.TotalSize - self:settextf("%iMB", sz) + self:settextf("%i%s", sz, translations["Megabytes"]) self:diffuse(colorByFileSize(sz)) end end, @@ -521,7 +546,7 @@ local function downloadsList() elseif bundle ~= nil then self:diffuse(COLORS:getDownloaderColor("NotInstalledIcon")) self:diffusealpha(isOver(self) and buttonHoverAlpha or 1) - if isOver(self) then toolTipOn("Download Bundle") end + if isOver(self) then toolTipOn(translations["DownloadBundle"]) end else self:diffusealpha(0) end @@ -533,14 +558,14 @@ local function downloadsList() -- the pack is already installed self:diffuse(COLORS:getDownloaderColor("InstalledIcon")) self:diffusealpha(1) - if isOver(self) then toolTipOn("Already Installed") end + if isOver(self) then toolTipOn(translations["AlreadyInstalled"]) end elseif downloadingPacksByName[name] ~= nil or queuedPacksByName[name] ~= nil then -- the pack is downloading or queued self:diffusealpha(0) else self:diffuse(COLORS:getDownloaderColor("NotInstalledIcon")) self:diffusealpha(isOver(self) and buttonHoverAlpha or 1) - if isOver(self) then toolTipOn("Download Pack") end + if isOver(self) then toolTipOn(translations["DownloadPack"]) end end end end, @@ -553,7 +578,6 @@ local function downloadsList() end pack:DownloadAndInstall(false) elseif bundle ~= nil then - local expanded = i % 2 == 0 and " Expanded" or "" local name = bundleTypes[index]:lower()..(i%2==0 and "-expanded" or "") DLMAN:DownloadCoreBundle(name) inBundles = false @@ -566,17 +590,17 @@ local function downloadsList() if pack ~= nil then local name = pack:GetName() if downloadingPacksByName[name] ~= nil then - toolTipOn("Currently Downloading") + toolTipOn(translations["CurrentlyDownloading"]) elseif queuedPacksByName[name] ~= nil then - toolTipOn("Queued") + toolTipOn(translations["Queued"]) elseif SONGMAN:DoesSongGroupExist(name) then - toolTipOn("Already Installed") + toolTipOn(translations["AlreadyInstalled"]) else - toolTipOn("Download Pack") + toolTipOn(translations["DownloadPack"]) self:diffusealpha(buttonHoverAlpha) end elseif bundle ~= nil then - toolTipOn("Download Bundle") + toolTipOn(translations["DownloadBundle"]) self:diffusealpha(buttonHoverAlpha) end end, @@ -604,7 +628,7 @@ local function downloadsList() elseif bundle ~= nil then self:diffuse(COLORS:getDownloaderColor("NotInstalledIcon")) self:diffusealpha(isOver(self) and buttonHoverAlpha or 1) - if isOver(self) then toolTipOn("Download Bundle (Mirror)") end + if isOver(self) then toolTipOn(translations["DownloadBundleMirrored"]) end else self:diffusealpha(0) end @@ -622,14 +646,14 @@ local function downloadsList() -- the pack is already installed self:diffuse(COLORS:getDownloaderColor("InstalledIcon")) self:diffusealpha(1) - if isOver(self) then toolTipOn("Already Installed") end + if isOver(self) then toolTipOn(translations["AlreadyInstalled"]) end elseif downloadingPacksByName[name] ~= nil or queuedPacksByName[name] ~= nil then -- the pack is downloading or queued self:diffusealpha(0) else self:diffuse(COLORS:getDownloaderColor("NotInstalledIcon")) self:diffusealpha(isOver(self) and buttonHoverAlpha or 1) - if isOver(self) then toolTipOn("Download Pack (Mirror)") end + if isOver(self) then toolTipOn(translations["DownloadPackMirrored"]) end end end end, @@ -655,17 +679,17 @@ local function downloadsList() if pack ~= nil then local name = pack:GetName() if downloadingPacksByName[name] ~= nil then - toolTipOn("Currently Downloading") + toolTipOn(translations["CurrentlyDownloading"]) elseif queuedPacksByName[name] ~= nil then - toolTipOn("Queued") + toolTipOn(translations["Queued"]) elseif SONGMAN:DoesSongGroupExist(name) then - toolTipOn("Already Installed") + toolTipOn(translations["AlreadyInstalled"]) else - toolTipOn("Download Pack (Mirror)") + toolTipOn(translations["DownloadPackMirrored"]) self:diffusealpha(buttonHoverAlpha) end elseif bundle ~= nil then - toolTipOn("Download Bundle (Mirror)") + toolTipOn(translations["DownloadBundleMirrored"]) self:diffusealpha(buttonHoverAlpha) end end, @@ -722,13 +746,13 @@ local function downloadsList() -- the pack is downloading self:diffusealpha(isOver(self:GetChild("BG")) and buttonHoverAlpha or 1) if isOver(self) then TOOLTIP:Hide() end - self:GetChild("Text"):settext("Cancel") + self:GetChild("Text"):settext(translations["Cancel"]) self:z(5) elseif queuedPacksByName[name] ~= nil then -- the pack is queued self:diffusealpha(isOver(self:GetChild("BG")) and buttonHoverAlpha or 1) if isOver(self) then TOOLTIP:Hide() end - self:GetChild("Text"):settext("Queued") + self:GetChild("Text"):settext(translations["Queued"]) self:z(5) else self:diffusealpha(0) @@ -941,7 +965,7 @@ local function downloadsList() bg:halign(0):valign(0) txt:zoom(nameHeaderSize) txt:maxwidth(width / nameHeaderSize - textZoomFudge) - txt:settext("Name") + txt:settext(translations["HeaderName"]) bg:zoomto(math.max(width/2, txt:GetZoomedWidth()), txt:GetZoomedHeight()) registerActorToColorConfigElement(txt, "main", "PrimaryText") end, @@ -972,7 +996,7 @@ local function downloadsList() bg:valign(0) txt:zoom(msdHeaderSize) txt:maxwidth(width / msdHeaderSize - textZoomFudge) - txt:settext("Avg") + txt:settext(translations["HeaderAverage"]) bg:zoomto(width, txt:GetZoomedHeight()) registerActorToColorConfigElement(txt, "main", "PrimaryText") end, @@ -1003,7 +1027,7 @@ local function downloadsList() bg:valign(0) txt:zoom(sizeHeaderSize) txt:maxwidth(width / sizeHeaderSize - textZoomFudge) - txt:settext("Size") + txt:settext(translations["HeaderSize"]) bg:zoomto(width, txt:GetZoomedHeight()) registerActorToColorConfigElement(txt, "main", "PrimaryText") end, diff --git a/Themes/Rebirth/BGAnimations/playerInfoFrame/main.lua b/Themes/Rebirth/BGAnimations/playerInfoFrame/main.lua index 0c1e459fbc..773db00f38 100644 --- a/Themes/Rebirth/BGAnimations/playerInfoFrame/main.lua +++ b/Themes/Rebirth/BGAnimations/playerInfoFrame/main.lua @@ -94,6 +94,7 @@ local ratios = { IconDownloadsHeight = 36 / 1080, IconDownloadsRightGap = 278 / 1920, IconDownloadsProgressBar1UpperGap = 51 / 1080, -- top of icon to top of bar + IconDownloadsProgressBar2UpperGap = 62.5 / 1080, IconDownloadsProgressBarHeight = 9 / 1080, IconDownloadsProgressBarWidth = 88 / 1920, IconRandomWidth = 41 / 1920, @@ -138,6 +139,7 @@ local actuals = { IconDownloadsHeight = ratios.IconDownloadsHeight * SCREEN_HEIGHT, IconDownloadsRightGap = ratios.IconDownloadsRightGap * SCREEN_WIDTH, IconDownloadsProgressBar1UpperGap = ratios.IconDownloadsProgressBar1UpperGap * SCREEN_HEIGHT, + IconDownloadsProgressBar2UpperGap = ratios.IconDownloadsProgressBar2UpperGap * SCREEN_HEIGHT, IconDownloadsProgressBarHeight = ratios.IconDownloadsProgressBarHeight * SCREEN_HEIGHT, IconDownloadsProgressBarWidth = ratios.IconDownloadsProgressBarWidth * SCREEN_WIDTH, IconRandomWidth = ratios.IconRandomWidth * SCREEN_WIDTH, @@ -148,6 +150,27 @@ local actuals = { IconSearchRightGap = ratios.IconSearchRightGap * SCREEN_WIDTH, } +local translations = { + LogOut = THEME:GetString("Header", "LogOut"), + LogIn = THEME:GetString("Header", "LogIn"), + Plays = THEME:GetString("Header", "Plays"), + ArrowsSmashed = THEME:GetString("Header", "ArrowsSmashed"), + PlayTime = THEME:GetString("Header", "PlayTime"), + PlayerRating = THEME:GetString("Header", "PlayerRating"), + PlayerRatings = THEME:GetString("Header", "PlayerRatings"), + OfflineRating = THEME:GetString("Header", "OfflineRating"), + OnlineRating = THEME:GetString("Header", "OnlineRating"), + Exit = THEME:GetString("Header", "Exit"), + Settings = THEME:GetString("Header", "Settings"), + Help = THEME:GetString("Header", "Help"), + Downloads = THEME:GetString("Header", "Downloads"), + Random = THEME:GetString("Header", "Random"), + Search = THEME:GetString("Header", "Search"), + DownloadingPacks = THEME:GetString("Header", "DownloadingPacks"), + QueuedPacks = THEME:GetString("Header", "QueuedPacks"), + UploadPercent = THEME:GetString("Header", "UploadPercent"), +} + -- the list of buttons and the lists of screens those buttons are allowed on -- if "All" is listed, the button is always active local screensAllowedForButtons = { @@ -187,6 +210,10 @@ local visualizerBins = 126 local leftTextBigSize = 0.7 local leftTextSmallSize = 0.65 local rightTextSize = 0.7 + +local versionTextSize = 0.45 +local versionPadding = 2 + local textzoomFudge = 5 -- for gaps in maxwidth -- a controllable hack to give more girth to the rating text (RightText) on smaller aspect ratios -- should push the visualizer further right and make less problems @@ -360,9 +387,9 @@ t[#t+1] = UIElements.SpriteButton(1, 1, nil) .. { MouseOverCommand = function(self) self:diffusealpha(hoverAlpha) if DLMAN:IsLoggedIn() then - TOOLTIP:SetText("Log out") + TOOLTIP:SetText(translations["LogOut"]) else - TOOLTIP:SetText("Log in") + TOOLTIP:SetText(translations["LogIn"]) end TOOLTIP:Show() end, @@ -431,7 +458,7 @@ t[#t+1] = Def.ActorFrame { self:halign(0) self:zoom(leftTextSmallSize) self:maxwidth((actuals.RightTextLeftGap - actuals.LeftTextLeftGap) / leftTextSmallSize - textzoomFudge) - self:settextf("%d plays", pcount) + self:settextf("%d %s", pcount, translations["Plays"]) registerActorToColorConfigElement(self, "main", "SecondaryText") end }, @@ -442,7 +469,7 @@ t[#t+1] = Def.ActorFrame { self:halign(0) self:zoom(leftTextSmallSize) self:maxwidth((actuals.RightTextLeftGap - actuals.LeftTextLeftGap) / leftTextSmallSize - textzoomFudge) - self:settextf("%s arrows smashed", strparrows) + self:settextf("%s %s", strparrows, translations["ArrowsSmashed"]) registerActorToColorConfigElement(self, "main", "SecondaryText") end, MouseOverCommand = function(self) @@ -456,13 +483,13 @@ t[#t+1] = Def.ActorFrame { end, }, LoadFont("Common Normal") .. { - Name = "Playtime", + Name = "PlayTime", InitCommand = function(self) self:y(actuals.LeftTextTopGap4) self:halign(0) self:zoom(leftTextSmallSize) self:maxwidth((actuals.RightTextLeftGap - actuals.LeftTextLeftGap) / leftTextSmallSize - textzoomFudge) - self:settextf("%s playtime", SecondsToHHMMSS(ptime)) + self:settextf("%s %s", SecondsToHHMMSS(ptime), translations["PlayTime"]) registerActorToColorConfigElement(self, "main", "SecondaryText") end } @@ -491,9 +518,9 @@ t[#t+1] = Def.ActorFrame { end, SetCommand = function(self) if DLMAN:IsLoggedIn() then - self:settext("Player Ratings:") + self:settextf("%s:", translations["PlayerRatings"]) else - self:settext("Player Rating:") + self:settextf("%s:", translations["PlayerRating"]) end end }, @@ -510,7 +537,7 @@ t[#t+1] = Def.ActorFrame { SetCommand = function(self) local offlinerating = profile:GetPlayerRating() if DLMAN:IsLoggedIn() then - self:settextf("Offline - %5.2f", offlinerating) + self:settextf("%s - %5.2f", translations["OfflineRating"], offlinerating) else self:settextf("%5.2f", offlinerating) end @@ -542,7 +569,7 @@ t[#t+1] = Def.ActorFrame { end, SetCommand = function(self) if DLMAN:IsLoggedIn() then - self:settextf("Online - %5.2f", DLMAN:GetSkillsetRating("Overall")) + self:settextf("%s - %5.2f", translations["OnlineRating"], DLMAN:GetSkillsetRating("Overall")) else self:settext("") end @@ -700,7 +727,7 @@ t[#t+1] = Def.ActorFrame { MouseOverCommand = function(self) if selectable(self:GetName()) then self:diffusealpha(hoverAlpha) - TOOLTIP:SetText(self:GetName()) + TOOLTIP:SetText(translations[self:GetName()]) TOOLTIP:Show() end end, @@ -738,7 +765,7 @@ t[#t+1] = Def.ActorFrame { MouseOverCommand = function(self) if selectable(self:GetName()) then self:diffusealpha(hoverAlpha) - TOOLTIP:SetText(self:GetName()) + TOOLTIP:SetText(translations[self:GetName()]) TOOLTIP:Show() end end, @@ -780,7 +807,7 @@ t[#t+1] = Def.ActorFrame { MouseOverCommand = function(self) if selectable(self:GetName()) then self:diffusealpha(hoverAlpha) - TOOLTIP:SetText(self:GetName()) + TOOLTIP:SetText(translations[self:GetName()]) TOOLTIP:Show() end end, @@ -823,7 +850,7 @@ t[#t+1] = Def.ActorFrame { MouseOverCommand = function(self) if selectable(self:GetName()) then self:diffusealpha(hoverAlpha) - TOOLTIP:SetText(self:GetName()) + TOOLTIP:SetText(translations[self:GetName()]) TOOLTIP:Show() end end, @@ -865,10 +892,10 @@ t[#t+1] = Def.ActorFrame { local result = {} for i,p in ipairs(dlpacks) do - result[#result+1] = "Downloading: " .. p:GetName() + result[#result+1] = translations["DownloadingPacks"] .. ": " .. p:GetName() end for i,p in ipairs(qpacks) do - result[#result+1] = "Queued: " .. p:GetName() + result[#result+1] = translations["QueuedPacks"] .. ": " .. p:GetName() end if #result > 0 then local ttstr = table.concat(result, "\n") @@ -928,6 +955,71 @@ t[#t+1] = Def.ActorFrame { AllDownloadsCompletedMessageCommand = function(self) self:diffusealpha(0) end + }, + UIElements.QuadButton(1, 1) .. { + Name = "Progress2BG", + InitCommand = function(self) + self:valign(0) + self:x(-actuals.IconDownloadsWidth/2) + self:y(actuals.IconDownloadsProgressBar2UpperGap) + self:zoomto(actuals.IconDownloadsProgressBarWidth, actuals.IconDownloadsProgressBarHeight) + self:diffusealpha(0) + registerActorToColorConfigElement(self, "downloader", "ProgressBarBackground") + end, + UploadProgressMessageCommand = function(self, params) + self.percent = params.percent + if isOver(self) then + self:playcommand("ToolTip") + end + + -- weird check here to throw out nan + if self.percent ~= nil and self.percent ~= 1 and self.percent == self.percent then + self:diffusealpha(downloadsProgress2BGAlpha) + else + self:diffusealpha(0) + end + end, + ToolTipCommand = function(self) + -- weird check here to throw out nan + if isOver(self) and self.percent ~= nil and self.percent ~= 1 and self.percent == self.percent then + local st = string.format("%s: %5.2f%%", translations["UploadPercent"], self.percent * 100) + TOOLTIP:SetText(st) + TOOLTIP:Show() + else + TOOLTIP:Hide() + end + end, + MouseOverCommand = function(self) + self:playcommand("ToolTip") + end, + MouseOutCommand = function(self) + self:playcommand("ToolTip") + end, + }, + Def.Quad { + Name = "Progress2Progress", + InitCommand = function(self) + self:halign(0):valign(0) + self:x(-actuals.IconDownloadsWidth/2 - actuals.IconDownloadsProgressBarWidth/2) + self:y(actuals.IconDownloadsProgressBar2UpperGap) + self:zoomto(actuals.IconDownloadsProgressBarWidth, actuals.IconDownloadsProgressBarHeight) + self:diffusealpha(0) + registerActorToColorConfigElement(self, "downloader", "ProgressBarFill") + end, + UploadProgressMessageCommand = function(self, params) + self.percent = params.percent + if isOver(self) then + self:playcommand("ToolTip") + end + + -- weird check here to throw out nan + if self.percent ~= nil and self.percent ~= 1 and self.percent == self.percent then + self:diffusealpha(downloadsProgress2Alpha) + self:zoomx(actuals.IconDownloadsProgressBarWidth * self.percent) + else + self:diffusealpha(0) + end + end, } }, UIElements.SpriteButton(1, 1, THEME:GetPathG("", "random")) .. { @@ -947,7 +1039,7 @@ t[#t+1] = Def.ActorFrame { MouseOverCommand = function(self) if selectable(self:GetName()) then self:diffusealpha(hoverAlpha) - TOOLTIP:SetText(self:GetName()) + TOOLTIP:SetText(translations[self:GetName()]) TOOLTIP:Show() end end, @@ -1007,7 +1099,7 @@ t[#t+1] = Def.ActorFrame { MouseOverCommand = function(self) if selectable(self:GetName()) then self:diffusealpha(hoverAlpha) - TOOLTIP:SetText(self:GetName()) + TOOLTIP:SetText(translations[self:GetName()]) TOOLTIP:Show() end end, @@ -1034,6 +1126,21 @@ t[#t+1] = Def.ActorFrame { } } + +t[#t+1] = LoadFont("Common Normal") .. { + Name = "GameVersion", + InitCommand = function(self) + self:x(actuals.Width - versionPadding) + self:y(versionPadding) + self:halign(1):valign(0) + self:zoom(versionTextSize) + self:maxwidth((SCREEN_WIDTH/2) / versionTextSize - textzoomFudge) + self:settextf("%s", GAMESTATE:GetEtternaVersion()) + registerActorToColorConfigElement(self, "main", "SecondaryText") + self:diffusealpha(0.6) + end +} + -- if off at first, cannot toggle at runtime -- for fps/compat reasons (this causes random crashes for some people) -- but if it is on at first, allow toggling visibility diff --git a/Themes/Rebirth/BGAnimations/playerInfoFrame/searchfilter.lua b/Themes/Rebirth/BGAnimations/playerInfoFrame/searchfilter.lua index 38159d5fbd..b60293f22c 100644 --- a/Themes/Rebirth/BGAnimations/playerInfoFrame/searchfilter.lua +++ b/Themes/Rebirth/BGAnimations/playerInfoFrame/searchfilter.lua @@ -25,6 +25,37 @@ local actuals = { LowerSectionHeight = ratios.LowerSectionHeight * SCREEN_HEIGHT, } +local translations = { + Title = THEME:GetString("SearchFilter", "Title"), + OmniSearch = THEME:GetString("SearchFilter", "OmniSearch"), + TitleSearch = THEME:GetString("SearchFilter", "TitleSearch"), + SubtitleSearch = THEME:GetString("SearchFilter", "SubtitleSearch"), + ArtistSearch = THEME:GetString("SearchFilter", "ArtistSearch"), + AuthorSearch = THEME:GetString("SearchFilter", "AuthorSearch"), + OverallFilter = THEME:GetString("SearchFilter", "OverallFilter"), + SteamFilter = THEME:GetString("SearchFilter", "SteamFilter"), + JumpstreamFilter = THEME:GetString("SearchFilter", "JumpstreamFilter"), + HandstreamFilter = THEME:GetString("SearchFilter", "HandstreamFilter"), + StaminaFilter = THEME:GetString("SearchFilter", "StaminaFilter"), + JackSpeedFilter = THEME:GetString("SearchFilter", "JackSpeedFilter"), + ChordjacksFilter = THEME:GetString("SearchFilter", "ChordjacksFilter"), + TechnicalFilter = THEME:GetString("SearchFilter", "TechnicalFilter"), + LengthFilter = THEME:GetString("SearchFilter", "LengthFilter"), + ClearPercentFilter = THEME:GetString("SearchFilter", "ClearPercentFilter"), + UpperBoundRate = THEME:GetString("SearchFilter", "UpperBoundRate"), + LowerBoundRate = THEME:GetString("SearchFilter", "LowerBoundRate"), + AnyAllMode = THEME:GetString("SearchFilter", "AnyAllMode"), + Any = THEME:GetString("SearchFilter", "Any"), + All = THEME:GetString("SearchFilter", "All"), + HighestSkillsetOnly = THEME:GetString("SearchFilter", "HighestSkillsetOnly"), + HardestChartOnly = THEME:GetString("SearchFilter", "HardestChartOnly"), + On = THEME:GetString("SearchFilter", "On"), + Off = THEME:GetString("SearchFilter", "Off"), + Results = THEME:GetString("SearchFilter", "Results"), + Reset = THEME:GetString("SearchFilter", "Reset"), + Apply = THEME:GetString("SearchFilter", "Apply"), +} + local visibleframeX = SCREEN_WIDTH - actuals.Width local visibleframeY = SCREEN_HEIGHT - actuals.Height local hiddenframeX = SCREEN_WIDTH @@ -99,11 +130,11 @@ local function upperSection() -- the base text for each line local entryTextTable = { - "Any Search", - "Title Search", - "Subtitle Search", - "Artist Search", - "Author Search", + translations["OmniSearch"], + translations["TitleSearch"], + translations["SubtitleSearch"], + translations["ArtistSearch"], + translations["AuthorSearch"], } -- used to actually search for things in WheelDataManager @@ -466,21 +497,21 @@ local function lowerSection() -- names for each filter line local filterCategoryTable = { - "Overall", - "Stream", - "Jumpstream", - "Handstream", - "Stamina", - "JackSpeed", - "Chordjacks", - "Technical", - "Length", - "Clear %", + translations["OverallFilter"], + translations["SteamFilter"], + translations["JumpstreamFilter"], + translations["HandstreamFilter"], + translations["StaminaFilter"], + translations["JackSpeedFilter"], + translations["ChordjacksFilter"], + translations["TechnicalFilter"], + translations["LengthFilter"], + translations["ClearPercentFilter"], } -- defines the bounds for each filter line -- if a bound is at either limit, it is considered infinite in that direction - -- so a Length filter of 1400,3600 is really >1400 + -- so a Length filter of 400,600 is really >400 -- or a Length filter of 0,360 is really <360 -- etc local filterCategoryLimits = { @@ -964,7 +995,7 @@ local function lowerSection() end, UpdateTextCommand = function(self) local maxrate = FILTERMAN:GetMaxFilterRate() - self:settextf("Max Rate: %2.1f", maxrate) + self:settextf("%s: %2.1f", translations["UpperBoundRate"], maxrate) end, MouseOverCommand = onHover, MouseOutCommand = onUnHover, @@ -992,7 +1023,7 @@ local function lowerSection() end, UpdateTextCommand = function(self) local maxrate = FILTERMAN:GetMinFilterRate() - self:settextf("Min Rate: %2.1f", maxrate) + self:settextf("%s: %2.1f", translations["LowerBoundRate"], maxrate) end, MouseOverCommand = onHover, MouseOutCommand = onUnHover, @@ -1019,8 +1050,8 @@ local function lowerSection() self:playcommand("UpdateText") end, UpdateTextCommand = function(self) - local txt = FILTERMAN:GetFilterMode() and "AND" or "OR" - self:settextf("Mode: %s", txt) + local txt = FILTERMAN:GetFilterMode() and translations["All"] or translations["Any"] + self:settextf("%s: %s", translations["AnyAllMode"], txt) end, MouseOverCommand = onHover, MouseOutCommand = onUnHover, @@ -1036,8 +1067,8 @@ local function lowerSection() self:playcommand("UpdateText") end, UpdateTextCommand = function(self) - local txt = FILTERMAN:GetHighestSkillsetsOnly() and "ON" or "OFF" - self:settextf("Highest Skillset Only: %s", txt) + local txt = FILTERMAN:GetHighestSkillsetsOnly() and translations["On"] or translations["Off"] + self:settextf("%s: %s", translations["HighestSkillsetOnly"], txt) end, MouseOverCommand = onHover, MouseOutCommand = onUnHover, @@ -1053,8 +1084,8 @@ local function lowerSection() self:playcommand("UpdateText") end, UpdateTextCommand = function(self) - local txt = FILTERMAN:GetHighestDifficultyOnly() and "ON" or "OFF" - self:settextf("Highest Difficulty Only: %s", txt) + local txt = FILTERMAN:GetHighestDifficultyOnly() and translations["On"] or translations["Off"] + self:settextf("%s: %s", translations["HardestChartOnly"], txt) end, MouseOverCommand = onHover, MouseOutCommand = onUnHover, @@ -1069,7 +1100,7 @@ local function lowerSection() UpdateTextCommand = function(self) local count1 = WHEELDATA:GetFilteredSongCount() local count2 = WHEELDATA:GetSongCount() - self:settextf("Matches: %d/%d", count1, count2) + self:settextf("%s: %d/%d", translations["Results"], count1, count2) end, FinishedSortMessageCommand = function(self) self:playcommand("UpdateText") @@ -1079,7 +1110,7 @@ local function lowerSection() t[#t+1] = filterMiscLine(7) .. { Name = "ResetLine", InitCommand = function(self) - self:settext("Reset") + self:settext(translations["Reset"]) end, MouseOverCommand = onHover, MouseOutCommand = onUnHover, @@ -1093,7 +1124,7 @@ local function lowerSection() t[#t+1] = filterMiscLine(8) .. { Name = "ApplyLine", InitCommand = function(self) - self:settext("Apply") + self:settext(translations["Apply"]) end, MouseOverCommand = onHover, MouseOutCommand = onUnHover, @@ -1140,7 +1171,7 @@ t[#t+1] = LoadFont("Common Normal") .. { self:xy(actuals.EdgePadding, actuals.TopLipHeight / 2) self:zoom(textSize) self:maxwidth(actuals.Width / textSize - textZoomFudge) - self:settext("Search and Filters") + self:settext(translations["Title"]) registerActorToColorConfigElement(self, "main", "PrimaryText") end } diff --git a/Themes/Rebirth/BGAnimations/playerInfoFrame/settings.lua b/Themes/Rebirth/BGAnimations/playerInfoFrame/settings.lua index a0a83fd93d..df71ed3cf9 100644 --- a/Themes/Rebirth/BGAnimations/playerInfoFrame/settings.lua +++ b/Themes/Rebirth/BGAnimations/playerInfoFrame/settings.lua @@ -76,6 +76,367 @@ local actuals = { GeneralBoxLeftGap = ratios.GeneralBoxLeftGap * SCREEN_WIDTH, } +-- there must be a better way to generate this table........ +local translations = { + NothingBound = THEME:GetString("Settings", "NothingBound"), + CurrentlyBinding = THEME:GetString("Settings", "CurrentlyBinding"), + Controller = THEME:GetString("Settings", "Controller"), + KeyBindingInstructions = THEME:GetString("Settings", "KeyBindingInstructions"), + StartBindingAll = THEME:GetString("Settings", "StartBindingAll"), + ShowGameplayBindings = THEME:GetString("Settings", "ShowGameplayBindings"), + ShowMenuBindings = THEME:GetString("Settings", "ShowMenuBindings"), + NewColorConfigPresetQuestion = THEME:GetString("Settings", "NewColorConfigPresetQuestion"), + NewColorConfigPresetUnknownError = THEME:GetString("Settings", "NewColorConfigPresetUnknownError"), + NewColorConfigPresetInputError = THEME:GetString("Settings", "NewColorConfigPresetInputError"), + CurrentPreset = THEME:GetString("Settings", "CurrentPreset"), + CurrentElement = THEME:GetString("Settings", "CurrentElement"), + CurrentColor = THEME:GetString("Settings", "CurrentColor"), + Undo = THEME:GetString("Settings", "Undo"), + UndoShortcut = THEME:GetString("Settings", "UndoShortcut"), + ResetToDefault = THEME:GetString("Settings", "ResetToDefault"), + Reset = THEME:GetString("Settings", "Reset"), + ResetShortcut = THEME:GetString("Settings", "ResetShortcut"), + SaveInstruction = THEME:GetString("Settings", "SaveInstruction"), + SaveChangesUnsaved = THEME:GetString("Settings", "SaveChangesUnsaved"), + SaveChanges = THEME:GetString("Settings", "SaveChanges"), + NewColorConfigPreset = THEME:GetString("Settings", "NewColorConfigPreset"), + NewColorConfigPresetInstruction = THEME:GetString("Settings", "NewColorConfigPresetInstruction"), + BrowsingColorCategories = THEME:GetString("Settings", "BrowsingColorCategories"), + BrowsingColorConfigPresets = THEME:GetString("Settings", "BrowsingColorConfigPresets"), + BrowsingElements = THEME:GetString("Settings", "BrowsingElements"), + CurrentlyEditing = THEME:GetString("Settings", "CurrentlyEditing"), + BackToPresets = THEME:GetString("Settings", "BackToPresets"), + BackToCategories = THEME:GetString("Settings", "BackToCategories"), + OptionsHeader = THEME:GetString("Settings", "OptionsHeader"), + ToggleChartPreview = THEME:GetString("Settings", "ToggleChartPreview"), + PageNamePlayer = THEME:GetString("Settings", "PageNamePlayer"), + PageNameGameplay = THEME:GetString("Settings", "PageNameGameplay"), + PageNameGraphics = THEME:GetString("Settings", "PageNameGraphics"), + PageNameSound = THEME:GetString("Settings", "PageNameSound"), + PageNameInput = THEME:GetString("Settings", "PageNameInput"), + PageNameProfiles = THEME:GetString("Settings", "PageNameProfiles"), + ["CategoryEssential Options"] = THEME:GetString("Settings", "CategoryEssential Options"), + ["CategoryAppearance Options"] = THEME:GetString("Settings", "CategoryAppearance Options"), + ["CategoryInvalidating Options"] = THEME:GetString("Settings", "CategoryInvalidating Options"), + ["CategoryGameplay Elements 1"] = THEME:GetString("Settings", "CategoryGameplay Elements 1"), + ["CategoryGameplay Elements 2"] = THEME:GetString("Settings", "CategoryGameplay Elements 2"), + ["CategoryGlobal Options"] = THEME:GetString("Settings", "CategoryGlobal Options"), + ["CategoryTheme Options"] = THEME:GetString("Settings", "CategoryTheme Options"), + ["CategorySound Options"] = THEME:GetString("Settings", "CategorySound Options"), + ["CategoryInput Options"] = THEME:GetString("Settings", "CategoryInput Options"), + ["CategoryProfile Options"] = THEME:GetString("Settings", "CategoryProfile Options"), + ["Color Config"] = THEME:GetString("Settings", "Color Config"), + Preview = THEME:GetString("Settings", "Preview"), + ["Customize Keybinds"] = THEME:GetString("Settings", "Customize Keybinds"), + Noteskin = THEME:GetString("Settings", "Noteskin"), + Hidden = THEME:GetString("Settings", "Hidden"), + Sudden = THEME:GetString("Settings", "Sudden"), + Stealth = THEME:GetString("Settings", "Stealth"), + Blink = THEME:GetString("Settings", "Blink"), + Dark = THEME:GetString("Settings", "Dark"), + Blind = THEME:GetString("Settings", "Blind"), + Split = THEME:GetString("Settings", "Split"), + Alternate = THEME:GetString("Settings", "Alternate"), + Cross = THEME:GetString("Settings", "Cross"), + Centered = THEME:GetString("Settings", "Centered"), + Drunk = THEME:GetString("Settings", "Drunk"), + Confusion = THEME:GetString("Settings", "Confusion"), + Tiny = THEME:GetString("Settings", "Tiny"), + Flip = THEME:GetString("Settings", "Flip"), + Invert = THEME:GetString("Settings", "Invert"), + Tornado = THEME:GetString("Settings", "Tornado"), + Tipsy = THEME:GetString("Settings", "Tipsy"), + Bumpy = THEME:GetString("Settings", "Bumpy"), + Beat = THEME:GetString("Settings", "Beat"), + Twirl = THEME:GetString("Settings", "Twirl"), + Roll = THEME:GetString("Settings", "Roll"), + Boost = THEME:GetString("Settings", "Boost"), + Brake = THEME:GetString("Settings", "Brake"), + Wave = THEME:GetString("Settings", "Wave"), + Expand = THEME:GetString("Settings", "Expand"), + Boomerang = THEME:GetString("Settings", "Boomerang"), + Backwards = THEME:GetString("Settings", "Backwards"), + Left = THEME:GetString("Settings", "Left"), + Right = THEME:GetString("Settings", "Right"), + Shuffle = THEME:GetString("Settings", "Shuffle"), + SoftShuffle = THEME:GetString("Settings", "SoftShuffle"), + SuperShuffle = THEME:GetString("Settings", "SuperShuffle"), + HRanShuffle = THEME:GetString("Settings", "HRanShuffle"), + Echo = THEME:GetString("Settings", "Echo"), + Stomp = THEME:GetString("Settings", "Stomp"), + JackJS = THEME:GetString("Settings", "JackJS"), + AnchorJS = THEME:GetString("Settings", "AnchorJS"), + IcyWorld = THEME:GetString("Settings", "IcyWorld"), + Planted = THEME:GetString("Settings", "Planted"), + Floored = THEME:GetString("Settings", "Floored"), + Twister = THEME:GetString("Settings", "Twister"), + HoldRolls = THEME:GetString("Settings", "HoldRolls"), + NoHolds = THEME:GetString("Settings", "NoHolds"), + NoRolls = THEME:GetString("Settings", "NoRolls"), + NoJumps = THEME:GetString("Settings", "NoJumps"), + NoHands = THEME:GetString("Settings", "NoHands"), + NoLifts = THEME:GetString("Settings", "NoLifts"), + NoFakes = THEME:GetString("Settings", "NoFakes"), + NoQuads = THEME:GetString("Settings", "NoQuads"), + NoStretch = THEME:GetString("Settings", "NoStretch"), + Little = THEME:GetString("Settings", "Little"), + Wide = THEME:GetString("Settings", "Wide"), + Big = THEME:GetString("Settings", "Big"), + Quick = THEME:GetString("Settings", "Quick"), + BMRize = THEME:GetString("Settings", "BMRize"), + Skippy = THEME:GetString("Settings", "Skippy"), + ["16bit"] = THEME:GetString("Settings", "16bit"), + ["32bit"] = THEME:GetString("Settings", "32bit"), + XMod = THEME:GetString("Settings", "XMod"), + CMod = THEME:GetString("Settings", "CMod"), + MMod = THEME:GetString("Settings", "MMod"), + Upscroll = THEME:GetString("Settings", "Upscroll"), + Downscroll = THEME:GetString("Settings", "Downscroll"), + On = THEME:GetString("Settings", "On"), + Off = THEME:GetString("Settings", "Off"), + Yes = THEME:GetString("Settings", "Yes"), + No = THEME:GetString("Settings", "No"), + Left = THEME:GetString("Settings", "Left"), + Right = THEME:GetString("Settings", "Right"), + Tips = THEME:GetString("Settings", "Tips"), + Quotes = THEME:GetString("Settings", "Quotes"), + Hold = THEME:GetString("Settings", "Hold"), + Instant = THEME:GetString("Settings", "Instant"), + Justice = THEME:GetString("Settings", "Justice"), + Overhead = THEME:GetString("Settings", "Overhead"), + Incoming = THEME:GetString("Settings", "Incoming"), + Space = THEME:GetString("Settings", "Space"), + Hallway = THEME:GetString("Settings", "Hallway"), + Distant = THEME:GetString("Settings", "Distant"), + ExtraMines = THEME:GetString("Settings", "ExtraMines"), + Regular = THEME:GetString("Settings", "Regular"), + EWMA = THEME:GetString("Settings", "EWMA"), + PersonalBest = THEME:GetString("Settings", "PersonalBest"), + GoalPercent = THEME:GetString("Settings", "GoalPercent"), + Windowed = THEME:GetString("Settings", "Windowed"), + Fullscreen = THEME:GetString("Settings", "Fullscreen"), + Borderless = THEME:GetString("Settings", "Borderless"), + Automatic = THEME:GetString("Settings", "Automatic"), + ForceOn = THEME:GetString("Settings", "ForceOn"), + ForceOff = THEME:GetString("Settings", "ForceOff"), + Online = THEME:GetString("Settings", "Online"), + Local = THEME:GetString("Settings", "Local"), + CustomizeGameplay = THEME:GetString("Settings", "CustomizeGameplay"), + CustomizeGameplayExplanation = THEME:GetString("Settings", "CustomizeGameplayExplanation"), + ScrollType = THEME:GetString("Settings", "ScrollType"), + ScrollTypeExplanation = THEME:GetString("Settings", "ScrollTypeExplanation"), + ScrollSpeed = THEME:GetString("Settings", "ScrollSpeed"), + ScrollSpeedExplanation = THEME:GetString("Settings", "ScrollSpeedExplanation"), + ScrollDirection = THEME:GetString("Settings", "ScrollDirection"), + ScrollDirectionExplanation = THEME:GetString("Settings", "ScrollDirectionExplanation"), + OptionNoteskin = THEME:GetString("Settings", "OptionNoteskin"), + OptionNoteskinExplanation = THEME:GetString("Settings", "OptionNoteskinExplanation"), + ReceptorSize = THEME:GetString("Settings", "ReceptorSize"), + ReceptorSizeExplanation = THEME:GetString("Settings", "ReceptorSizeExplanation"), + JudgeDifficulty = THEME:GetString("Settings", "JudgeDifficulty"), + JudgeDifficultyExplanation = THEME:GetString("Settings", "JudgeDifficultyExplanation"), + Mirror = THEME:GetString("Settings", "Mirror"), + MirrorExplanation = THEME:GetString("Settings", "MirrorExplanation"), + GlobalOffset = THEME:GetString("Settings", "GlobalOffset"), + GlobalOffsetExplanation = THEME:GetString("Settings", "GlobalOffsetExplanation"), + VisualDelay = THEME:GetString("Settings", "VisualDelay"), + VisualDelayExplanation = THEME:GetString("Settings", "VisualDelayExplanation"), + GameMode = THEME:GetString("Settings", "GameMode"), + GameModeExplanation = THEME:GetString("Settings", "GameModeExplanation"), + FailType = THEME:GetString("Settings", "FailType"), + FailTypeExplanation = THEME:GetString("Settings", "FailTypeExplanation"), + CustomizeKeybinds = THEME:GetString("Settings", "CustomizeKeybinds"), + CustomizeKeybindsExplanation = THEME:GetString("Settings", "CustomizeKeybindsExplanation"), + CustomizeKeybindsButton = THEME:GetString("Settings", "CustomizeKeybindsButton"), + PracticeMode = THEME:GetString("Settings", "PracticeMode"), + PracticeModeExplanation = THEME:GetString("Settings", "PracticeModeExplanation"), + PracticeModeButton = THEME:GetString("Settings", "PracticeModeButton"), + Appearance = THEME:GetString("Settings", "Appearance"), + AppearanceExplanation = THEME:GetString("Settings", "AppearanceExplanation"), + HiddenOffset = THEME:GetString("Settings", "HiddenOffset"), + HiddenOffsetExplanation = THEME:GetString("Settings", "HiddenOffsetExplanation"), + SuddenOffset = THEME:GetString("Settings", "SuddenOffset"), + SuddenOffsetExplanation = THEME:GetString("Settings", "SuddenOffsetExplanation"), + Perspective = THEME:GetString("Settings", "Perspective"), + PerspectiveExplanation = THEME:GetString("Settings", "PerspectiveExplanation"), + PerspectiveIntensity = THEME:GetString("Settings", "PerspectiveIntensity"), + PerspectiveIntensityExplanation = THEME:GetString("Settings", "PerspectiveIntensityExplanation"), + HidingModifiers = THEME:GetString("Settings", "HidingModifiers"), + HidingModifierExplanation = THEME:GetString("Settings", "HidingModifierExplanation"), + Hidenote = THEME:GetString("Settings", "Hidenote"), + HidenoteExplanation = THEME:GetString("Settings", "HidenoteExplanation"), + CenterPlayer1 = THEME:GetString("Settings", "CenterPlayer1"), + CenterPlayer1Explanation = THEME:GetString("Settings", "CenterPlayer1Explanation"), + NoteFieldFilter = THEME:GetString("Settings", "NoteFieldFilter"), + NoteFieldFilterExplanation = THEME:GetString("Settings", "NoteFieldFilterExplanation"), + BGBrightness = THEME:GetString("Settings", "BGBrightness"), + BGBrightnessExplanation = THEME:GetString("Settings", "BGBrightnessExplanation"), + ReplayModEmulation = THEME:GetString("Settings", "ReplayModEmulation"), + ReplayModEmulationExplanation = THEME:GetString("Settings", "ReplayModEmulationExplanation"), + ExtraScrollMods = THEME:GetString("Settings", "ExtraScrollMods"), + ExtraScrollModsExplanation = THEME:GetString("Settings", "ExtraScrollModsExplanation"), + FunEffects = THEME:GetString("Settings", "FunEffects"), + FunEffectsExplanation = THEME:GetString("Settings", "FunEffectsExplanation"), + Acceleration = THEME:GetString("Settings", "Acceleration"), + AccelerationExplanation = THEME:GetString("Settings", "AccelerationExplanation"), + Mines = THEME:GetString("Settings", "Mines"), + MinesExplanation = THEME:GetString("Settings", "MinesExplanation"), + Turn = THEME:GetString("Settings", "Turn"), + TurnExplanation = THEME:GetString("Settings", "TurnExplanation"), + PatternTransform = THEME:GetString("Settings", "PatternTransform"), + PatternTransformExplanation = THEME:GetString("Settings", "PatternTransformExplanation"), + HoldTransform = THEME:GetString("Settings", "HoldTransform"), + HoldTransformExplanation = THEME:GetString("Settings", "HoldTransformExplanation"), + RemoveMods = THEME:GetString("Settings", "RemoveMods"), + RemoveModsExplanation = THEME:GetString("Settings", "RemoveModsExplanation"), + InsertMods = THEME:GetString("Settings", "InsertMods"), + InsertModsExplanation = THEME:GetString("Settings", "InsertModsExplanation"), + BPMDisplay = THEME:GetString("Settings", "BPMDisplay"), + BPMDisplayExplanation = THEME:GetString("Settings", "BPMDisplayExplanation"), + RateDisplay = THEME:GetString("Settings", "RateDisplay"), + RateDisplayExplanation = THEME:GetString("Settings", "RateDisplayExplanation"), + PercentDisplay = THEME:GetString("Settings", "PercentDisplay"), + PercentDisplayExplanation = THEME:GetString("Settings", "PercentDisplayExplanation"), + MeanDisplay = THEME:GetString("Settings", "MeanDisplay"), + MeanDisplayExplanation = THEME:GetString("Settings", "MeanDisplayExplanation"), + EWMADisplay = THEME:GetString("Settings", "EWMADisplay"), + EWMADisplayExplanation = THEME:GetString("Settings", "EWMADisplayExplanation"), + StdDevDisplay = THEME:GetString("Settings", "StdDevDisplay"), + StdDevDisplayExplanation = THEME:GetString("Settings", "StdDevDisplayExplanation"), + ErrorBar = THEME:GetString("Settings", "ErrorBar"), + ErrorBarExplanation = THEME:GetString("Settings", "ErrorBarExplanation"), + ErrorBarCount = THEME:GetString("Settings", "ErrorBarCount"), + ErrorBarCountExplanation = THEME:GetString("Settings", "ErrorBarCountExplanation"), + FullProgressBar = THEME:GetString("Settings", "FullProgressBar"), + FullProgressBarExplanation = THEME:GetString("Settings", "FullProgressBarExplanation"), + MiniProgressBar = THEME:GetString("Settings", "MiniProgressBar"), + MiniProgressBarExplanation = THEME:GetString("Settings", "MiniProgressBarExplanation"), + Leaderboard = THEME:GetString("Settings", "Leaderboard"), + LeaderboardExplanation = THEME:GetString("Settings", "LeaderboardExplanation"), + PlayerInfo = THEME:GetString("Settings", "PlayerInfo"), + PlayerInfoExplanation = THEME:GetString("Settings", "PlayerInfoExplanation"), + TargetTracker = THEME:GetString("Settings", "TargetTracker"), + TargetTrackerExplanation = THEME:GetString("Settings", "TargetTrackerExplanation"), + TargetTrackerMode = THEME:GetString("Settings", "TargetTrackerMode"), + TargetTrackerModeExplanation = THEME:GetString("Settings", "TargetTrackerModeExplanation"), + TargetTrackerGoal = THEME:GetString("Settings", "TargetTrackerGoal"), + TargetTrackerGoalExplanation = THEME:GetString("Settings", "TargetTrackerGoalExplanation"), + LaneCover = THEME:GetString("Settings", "LaneCover"), + LaneCoverExplanation = THEME:GetString("Settings", "LaneCoverExplanation"), + JudgeCounter = THEME:GetString("Settings", "JudgeCounter"), + JudgeCounterExplanation = THEME:GetString("Settings", "JudgeCounterExplanation"), + JudgmentText = THEME:GetString("Settings", "JudgmentText"), + JudgmentTextExplanation = THEME:GetString("Settings", "JudgmentTextExplanation"), + JudgmentAnimations = THEME:GetString("Settings", "JudgmentAnimations"), + JudgmentAnimationsExplanation = THEME:GetString("Settings", "JudgmentAnimationsExplanation"), + ComboTweens = THEME:GetString("Settings", "ComboTweens"), + ComboTweensExplanation = THEME:GetString("Settings", "ComboTweensExplanation"), + ComboText = THEME:GetString("Settings", "ComboText"), + ComboTextExplanation = THEME:GetString("Settings", "ComboTextExplanation"), + ComboGlow = THEME:GetString("Settings", "ComboGlow"), + ComboGlowExplanation = THEME:GetString("Settings", "ComboGlowExplanation"), + ComboLabel = THEME:GetString("Settings", "ComboLabel"), + ComboLabelExplanation = THEME:GetString("Settings", "ComboLabelExplanation"), + CBHighlights = THEME:GetString("Settings", "CBHighlights"), + CBHighlightsExplanation = THEME:GetString("Settings", "CBHighlightsExplanation"), + MeasureCounter = THEME:GetString("Settings", "MeasureCounter"), + MeasureCounterExplanation = THEME:GetString("Settings", "MeasureCounterExplanation"), + MeasureLines = THEME:GetString("Settings", "MeasureLines"), + MeasureLinesExplaantion = THEME:GetString("Settings", "MeasureLinesExplaantion"), + NPSDisplay = THEME:GetString("Settings", "NPSDisplay"), + NPSDisplayExplanation = THEME:GetString("Settings", "NPSDisplayExplanation"), + NPSGraph = THEME:GetString("Settings", "NPSGraph"), + NPSGraphExplanation = THEME:GetString("Settings", "NPSGraphExplanation"), + Language = THEME:GetString("Settings", "Language"), + LanguageExplanation = THEME:GetString("Settings", "LanguageExplanation"), + Theme = THEME:GetString("Settings", "Theme"), + ThemeExplanation = THEME:GetString("Settings", "ThemeExplanation"), + DisplayMode = THEME:GetString("Settings", "DisplayMode"), + DisplayModeExplanation = THEME:GetString("Settings", "DisplayModeExplanation"), + AspectRatio = THEME:GetString("Settings", "AspectRatio"), + AspectRatioExplanation = THEME:GetString("Settings", "AspectRatioExplanation"), + DisplayResolution = THEME:GetString("Settings", "DisplayResolution"), + DisplayResolutionExplanation = THEME:GetString("Settings", "DisplayResolutionExplanation"), + RefreshRate = THEME:GetString("Settings", "RefreshRate"), + RefreshRateExplanation = THEME:GetString("Settings", "RefreshRateExplanation"), + ColorDepth = THEME:GetString("Settings", "ColorDepth"), + ColorDepthExplanation = THEME:GetString("Settings", "ColorDepthExplanation"), + HighResTextures = THEME:GetString("Settings", "HighResTextures"), + HighResTexturesExplanation = THEME:GetString("Settings", "HighResTexturesExplanation"), + TextureResolution = THEME:GetString("Settings", "TextureResolution"), + TextureResolutionExplanation = THEME:GetString("Settings", "TextureResolutionExplanation"), + VSync = THEME:GetString("Settings", "VSync"), + VSyncExplanation = THEME:GetString("Settings", "VSyncExplanation"), + FastNoteRendering = THEME:GetString("Settings", "FastNoteRendering"), + FastNoteRenderingExplanation = THEME:GetString("Settings", "FastNoteRenderingExplanation"), + ShowStats = THEME:GetString("Settings", "ShowStats"), + ShowStatsExplanation = THEME:GetString("Settings", "ShowStatsExplanation"), + TapGlow = THEME:GetString("Settings", "TapGlow"), + TapGlowExplanation = THEME:GetString("Settings", "TapGlowExplanation"), + MusicWheelPosition = THEME:GetString("Settings", "MusicWheelPosition"), + MusicWheelPositionExplanation = THEME:GetString("Settings", "MusicWheelPositionExplanation"), + MusicWheelBanners = THEME:GetString("Settings", "MusicWheelBanners"), + MusicWheelBannersExplanation = THEME:GetString("Settings", "MusicWheelBannersExplanation"), + VideoBanners = THEME:GetString("Settings", "VideoBanners"), + VideoBannersExplanation = THEME:GetString("Settings", "VideoBannersExplanation"), + ShowBGs = THEME:GetString("Settings", "ShowBGs"), + ShowBGsExplanation = THEME:GetString("Settings", "ShowBGsExplanation"), + ShowBanners = THEME:GetString("Settings", "ShowBanners"), + ShowBannersExplanation = THEME:GetString("Settings", "ShowBannersExplanation"), + BGBannerColor = THEME:GetString("Settings", "BGBannerColor"), + BGBannerColorExplanation = THEME:GetString("Settings", "BGBannerColorExplanation"), + AllowBGChanges = THEME:GetString("Settings", "AllowBGChanges"), + AllowBGChangesExplanation = THEME:GetString("Settings", "AllowBGChangesExplanation"), + EasterEggs = THEME:GetString("Settings", "EasterEggs"), + EasterEggsExplanation = THEME:GetString("Settings", "EasterEggsExplanation"), + Visualizer = THEME:GetString("Settings", "Visualizer"), + VisualizerExplanation = THEME:GetString("Settings", "VisualizerExplanation"), + MidGrades = THEME:GetString("Settings", "MidGrades"), + MidGradesExplanation = THEME:GetString("Settings", "MidGradesExplanation"), + SSRNorm = THEME:GetString("Settings", "SSRNorm"), + SSRNormExplanation = THEME:GetString("Settings", "SSRNormExplanation"), + ShowLyrics = THEME:GetString("Settings", "ShowLyrics"), + ShowLyricsExplanation = THEME:GetString("Settings", "ShowLyricsExplanation"), + Transliteration = THEME:GetString("Settings", "Transliteration"), + TransliterationExplanation = THEME:GetString("Settings", "TransliterationExplanation"), + TipType = THEME:GetString("Settings", "TipType"), + TipTypeExplanation = THEME:GetString("Settings", "TipTypeExplanation"), + BGFit = THEME:GetString("Settings", "BGFit"), + BGFitExplanation = THEME:GetString("Settings", "BGFitExplanation"), + ColorConfig = THEME:GetString("Settings", "ColorConfig"), + ColorConfigExplanation = THEME:GetString("Settings", "ColorConfigExplanation"), + ColorConfigButton = THEME:GetString("Settings", "ColorConfigButton"), + AssetSettings = THEME:GetString("Settings", "AssetSettings"), + AssetSettingsExplanation = THEME:GetString("Settings", "AssetSettingsExplanation"), + AssetSettingsButton = THEME:GetString("Settings", "AssetSettingsButton"), + Volume = THEME:GetString("Settings", "Volume"), + VolumeExplanation = THEME:GetString("Settings", "VolumeExplanation"), + MenuSounds = THEME:GetString("Settings", "MenuSounds"), + MenuSoundsExplanation = THEME:GetString("Settings", "MenuSoundsExplanation"), + MineSounds = THEME:GetString("Settings", "MineSounds"), + MineSoundsExplanation = THEME:GetString("Settings", "MineSoundsExplanation"), + PitchRates = THEME:GetString("Settings", "PitchRates"), + PitchRatesExplanation = THEME:GetString("Settings", "PitchRatesExplanation"), + CalibrateAudioSync = THEME:GetString("Settings", "CalibrateAudioSync"), + CalibrateAudioSyncExplanation = THEME:GetString("Settings", "CalibrateAudioSyncExplanation"), + CalibrateAudioSyncButton = THEME:GetString("Settings", "CalibrateAudioSyncButton"), + BackDelayed = THEME:GetString("Settings", "BackDelayed"), + BackDelayedExplanation = THEME:GetString("Settings", "BackDelayedExplanation"), + StartGiveUp = THEME:GetString("Settings", "StartGiveUp"), + StartGiveUpExplanation = THEME:GetString("Settings", "StartGiveUpExplanation"), + Debounce = THEME:GetString("Settings", "Debounce"), + DebounceExplanation = THEME:GetString("Settings", "DebounceExplanation"), + TestInput = THEME:GetString("Settings", "TestInput"), + TestInputExplanation = THEME:GetString("Settings", "TestInputExplanation"), + TestInputButton = THEME:GetString("Settings", "TestInputButton"), + CreateProfile = THEME:GetString("Settings", "CreateProfile"), + CreateProfileExplanation = THEME:GetString("Settings", "CreateProfileExplanation"), + CreateProfileButton = THEME:GetString("Settings", "CreateProfileButton"), + RenameProfile = THEME:GetString("Settings", "RenameProfile"), + RenameProfileExplanation = THEME:GetString("Settings", "RenameProfileExplanation"), + RenameProfileButton = THEME:GetString("Settings", "RenameProfileButton"), +} + local visibleframeY = SCREEN_HEIGHT - actuals.Height local animationSeconds = 0.1 local focused = false @@ -166,6 +527,9 @@ local t = Def.ActorFrame { focused = false end end, + ChartPreviewToggleMessageCommand = function(self) + self:playcommand("GeneralTabSet") + end, FinishFocusingCommand = function(self) focused = true CONTEXTMAN:SetFocusedContextSet(SCREENMAN:GetTopScreen():GetName(), "Settings") @@ -273,7 +637,7 @@ local function leftFrame() end, ShowLeftCommand = function(self, params) if params and params.name then - self:settext(params.name) + self:settext(translations[params.name]) end end, @@ -861,7 +1225,7 @@ local function leftFrame() if buttonmapped then self:settext(buttonmapped:gsub("Key ", "")) else - self:settext("none") + self:settext(translations["NothingBound"]) end end, } @@ -942,7 +1306,7 @@ local function leftFrame() if buttonmapped then self:settext(buttonmapped:gsub("Key ", "")) else - self:settext("none") + self:settext(translations["NothingBound"]) end end, }, @@ -986,11 +1350,11 @@ local function leftFrame() end if currentlyBinding and not inMenuPage then - self:settextf("Currently Binding: %s (Controller %s)", currentKey, currentController) + self:settextf("%s: %s (%s %s)", translations["CurrentlyBinding"], currentKey, translations["Controller"], currentController) elseif currentlyBinding and inMenuPage then - self:settextf("Currently Binding: %s", currentKey) + self:settextf("%s: %s", translations["CurrentlyBinding"], currentKey) else - self:settext("Currently Binding: ") + self:settextf("%s: ", translations["CurrentlyBinding"]) end end, StartedBindingMessageCommand = function(self) @@ -1011,7 +1375,7 @@ local function leftFrame() self:zoom(keyinstructionsTextSize) self:wrapwidthpixels(actuals.LeftWidth - 10) self:maxheight((actuals.Height / 4 - actuals.TopLipHeight * 1.5) / keyinstructionsTextSize) - self:settext("Select a button to rebind with mouse or keyboard.\nPress Escape or click to cancel binding.") + self:settext(translations["KeyBindingInstructions"]) registerActorToColorConfigElement(self, "main", "SecondaryText") end, }, @@ -1025,7 +1389,7 @@ local function leftFrame() self:xy(actuals.EdgePadding, actuals.Height/2 + actuals.Height/4) txt:zoom(bindingChoicesTextSize) txt:maxwidth(actuals.LeftWidth / bindingChoicesTextSize) - txt:settext("Start Binding All") + txt:settext(translations["StartBindingAll"]) registerActorToColorConfigElement(txt, "main", "PrimaryText") bg:zoomto(txt:GetZoomedWidth(), txt:GetZoomedHeight() * textButtonHeightFudgeScalarMultiplier) bg:diffusealpha(0.2) @@ -1079,9 +1443,9 @@ local function leftFrame() local txt = self:GetChild("Text") local bg = self:GetChild("BG") if inMenuPage then - txt:settext("View Gameplay Keybindings") + txt:settext(translations["ShowGameplayBindings"]) else - txt:settext("View Menu Keybindings") + txt:settext(translations["ShowMenuBindings"]) end bg:zoomto(txt:GetZoomedWidth(), txt:GetZoomedHeight() * textButtonHeightFudgeScalarMultiplier) end, @@ -1159,21 +1523,18 @@ local function leftFrame() InitCommand = function(self) -- centered horizontally and vertically self:x(actuals.LeftWidth / 2) - self:y(actuals.Height / 4) + self:y(0) end, BeginCommand = function(self) -- take the long road to find the actual chart preview actor local realnotefieldpreview = SCREENMAN:GetTopScreen():safeGetChild( - "RightFrame", - "GeneralBoxFile", - "Container", - "GeneralPageFile", "ChartPreviewFile", "NoteField" ) if realnotefieldpreview ~= nil then self:SetTarget(realnotefieldpreview) self:addx(-realnotefieldpreview:GetX()) + self:zoom(0.9) else print("It appears that chart preview is not where it should be ....") end @@ -1592,7 +1953,7 @@ local function leftFrame() end on() end - local question = "NEW COLOR CONFIG PRESET\nPlease enter a new preset name." + local question = translations["NewColorConfigPresetQuestion"] askForInputStringWithFunction( question, 128, @@ -1612,13 +1973,13 @@ local function leftFrame() if result then result = COLORS:newColorPreset(answer:lower()) if not result then - SCREENMAN:GetTopScreen():GetChild("Question"):settext(question .. "\nThere was an issue creating the new color config preset. You may try again.\nTo exit, press Esc.") + SCREENMAN:GetTopScreen():GetChild("Question"):settext(question .. "\n" .. translations["NewColorConfigPresetUnknownError"]) return false, "Response invalid." else return true, "Response invalid." -- the 2nd param doesnt matter here end else - SCREENMAN:GetTopScreen():GetChild("Question"):settext(question .. "\nDo not leave this space blank. Do not use illegal characters.\nTo exit, press Esc.") + SCREENMAN:GetTopScreen():GetChild("Question"):settext(question .. "\n" .. translations["NewColorConfigPresetInputError"]) return false, "Response invalid." end end, @@ -1907,11 +2268,11 @@ local function leftFrame() self:y(textLineSeparation * 1) self:zoom(colorConfigTextSize) self:maxwidth(widthOfTheRightSide / colorConfigChoiceTextSize - textZoomFudge) - self:settext("Current preset:") + self:settextf("%s:", translations["CurrentPreset"]) registerActorToColorConfigElement(self, "main", "PrimaryText") end, SetCommand = function(self) - self:settextf("Current preset: %s", selectedpreset) + self:settextf("%s: %s", translations["CurrentPreset"], selectedpreset) end, ColorConfigSelectionStateChangedMessageCommand = function(self) self:playcommand("Set") @@ -1924,11 +2285,11 @@ local function leftFrame() self:y(textLineSeparation * 2) self:zoom(colorConfigTextSize) self:maxwidth(widthOfTheRightSide / colorConfigChoiceTextSize - textZoomFudge) - self:settext("Current element:") + self:settextf("%s:", translations["CurrentElement"]) registerActorToColorConfigElement(self, "main", "PrimaryText") end, SetCommand = function(self) - self:settextf("Current element: %s", selectedelement) + self:settextf("%s: %s", translations["CurrentElement"], selectedelement) end, ColorConfigSelectionStateChangedMessageCommand = function(self) self:playcommand("Set") @@ -1941,7 +2302,7 @@ local function leftFrame() self:y(textLineSeparation * 3) self:zoom(colorConfigTextSize) self:maxwidth(widthOfTheRightSide/2 / colorConfigChoiceTextSize - textZoomFudge) - self:settext("Current color") + self:settext(translations["CurrentColor"]) registerActorToColorConfigElement(self, "main", "PrimaryText") end }, @@ -2038,7 +2399,7 @@ local function leftFrame() txt:maxwidth(widthOfTheRightSide / 2 / colorConfigTextSize) self:y(textLineSeparation * 6) bg:y(1) - txt:settext("Undo") + txt:settext(translations["Undo"]) registerActorToColorConfigElement(txt, "main", "PrimaryText") bg:zoomto(txt:GetZoomedWidth(), txt:GetZoomedHeight() * textButtonHeightFudgeScalarMultiplier) self.alphaDeterminingFunction = function(self) @@ -2046,7 +2407,7 @@ local function leftFrame() local disabledmultiplier = selectionstate ~= "editing" and 0.3 or 1 self:diffusealpha(1 * hovermultiplier * disabledmultiplier) if isOver(bg) then - TOOLTIP:SetText("Undo: Alt-Delete") + TOOLTIP:SetText(translations["Undo"] .. ": " .. translations["UndoShortcut"]) TOOLTIP:Show() else TOOLTIP:Hide() @@ -2083,7 +2444,7 @@ local function leftFrame() self:x(widthOfTheRightSide) self:y(textLineSeparation * 6) bg:y(1) - txt:settext("Reset to Default") + txt:settext(translations["ResetToDefault"]) registerActorToColorConfigElement(txt, "main", "PrimaryText") bg:zoomto(txt:GetZoomedWidth(), txt:GetZoomedHeight() * textButtonHeightFudgeScalarMultiplier) self.alphaDeterminingFunction = function(self) @@ -2091,7 +2452,7 @@ local function leftFrame() local disabledmultiplier = selectionstate ~= "editing" and 0.3 or 1 self:diffusealpha(1 * hovermultiplier * disabledmultiplier) if isOver(bg) then - TOOLTIP:SetText("Reset: Ctrl-Delete") + TOOLTIP:SetText(translations["Reset"] .. ": " .. translations["ResetShortcut"]) TOOLTIP:Show() else TOOLTIP:Hide() @@ -2134,7 +2495,7 @@ local function leftFrame() local disabledmultiplier = selectionstate ~= "editing" and 0.3 or 1 self:diffusealpha(1 * hovermultiplier * disabledmultiplier) if isOver(bg) then - TOOLTIP:SetText("Save (or press Enter)") + TOOLTIP:SetText(translations["SaveInstruction"]) TOOLTIP:Show() else TOOLTIP:Hide() @@ -2145,9 +2506,9 @@ local function leftFrame() local txt = self:GetChild("Text") local bg = self:GetChild("BG") if aboutToSave then - txt:settext("Save Changes (Not Saved!)") + txt:settext(translations["SaveChangesUnsaved"]) else - txt:settext("Save Changes") + txt:settext(translations["SaveChanges"]) end bg:zoomto(txt:GetZoomedWidth(), txt:GetZoomedHeight() * textButtonHeightFudgeScalarMultiplier) end, @@ -2180,14 +2541,14 @@ local function leftFrame() bg:y(1) txt:zoom(colorConfigTextSize) txt:maxwidth(widthOfTheRightSide / colorConfigChoiceTextSize - textZoomFudge) - txt:settext("New Color Config Preset") + txt:settext(translations["NewColorConfigPreset"]) registerActorToColorConfigElement(txt, "main", "PrimaryText") bg:zoomto(txt:GetZoomedWidth(), txt:GetZoomedHeight() * textButtonHeightFudgeScalarMultiplier) self.alphaDeterminingFunction = function(self) local hovermultiplier = isOver(bg) and buttonHoverAlpha or 1 self:diffusealpha(1 * hovermultiplier) if isOver(bg) then - TOOLTIP:SetText("New Preset: Ctrl-N") + TOOLTIP:SetText(translations["NewColorConfigPresetInstruction"]) TOOLTIP:Show() else TOOLTIP:Hide() @@ -2232,13 +2593,13 @@ local function leftFrame() end, UpdateColorConfigDisplayCommand = function(self) if selectionstate == "category" then - self:settext("Browsing Color Categories") + self:settext(translations["BrowsingColorCategories"]) elseif selectionstate == "preset" then - self:settext("Browsing Color Config Presets") + self:settext(translations["BrowsingColorConfigPresets"]) elseif selectionstate == "element" then - self:settext("Browsing Elements in '"..selectedcategory.."'") + self:settextf("%s '%s'", translations["BrowsingElements"], selectedcategory) elseif selectionstate == "editing" then - self:settext("Browsing Elements in '"..selectedcategory.."' (editing)") + self:settextf("%s '%s' %s", translations["BrowsingElements"], selectedcategory, translations["CurrentlyEditing"]) end end, ColorConfigSelectionStateChangedMessageCommand = function(self) @@ -2306,13 +2667,13 @@ local function leftFrame() local txt = self:GetChild("Text") local bg = self:GetChild("BG") if selectionstate == "category" then - txt:settext("Back to Presets") + txt:settext(translations["BackToPresets"]) elseif selectionstate == "preset" then txt:settext(" ") elseif selectionstate == "element" then - txt:settext("Back to Categories") + txt:settext(translations["BackToCategories"]) elseif selectionstate == "editing" then - txt:settext("Back to Categories") + txt:settext(translations["BackToCategories"]) end bg:zoomto(txt:GetZoomedWidth(), txt:GetZoomedHeight() * textButtonHeightFudgeScalarMultiplier) self:alphaDeterminingFunction() @@ -2517,7 +2878,7 @@ local function rightFrame() end if setGraphics and not setGame and not setTheme then THEME:SetTheme(THEME:GetCurThemeName()) - elseif setGame or setTheme then + elseif setGame or setTheme or setLanguage then local gameToUse = setGame or GAMESTATE:GetCurrentGame():GetName() GAMEMAN:SetGame(gameToUse, themeToUse) end @@ -2597,7 +2958,7 @@ local function rightFrame() self:xy(actuals.EdgePadding, actuals.TopLipHeight / 2) self:zoom(titleTextSize) self:maxwidth((actuals.RightWidth - actuals.EdgePadding*2) / titleTextSize - textZoomFudge) - self:settext("Options") + self:settext(translations["OptionsHeader"]) registerActorToColorConfigElement(self, "main", "PrimaryText") end }, @@ -2648,7 +3009,7 @@ local function rightFrame() txt:halign(0) txt:zoom(previewButtonTextSize) txt:maxwidth(actuals.RightWidth / 2 / previewButtonTextSize - textZoomFudge) - txt:settext("Toggle Chart Preview") + txt:settext(translations["ToggleChartPreview"]) registerActorToColorConfigElement(txt, "main", "SecondaryText") bg:halign(0) @@ -2741,9 +3102,10 @@ local function rightFrame() end -- for convenience to generate a choice table for a float interface setting - local function floatSettingChoice(visibleName, funcName, enabledValue, offValue) + local function floatSettingChoice(name, funcName, enabledValue, offValue) return { - Name = visibleName, + Name = name, + DisplayName = translations[funcName], ChosenFunction = function() local po = getPlayerOptions() if po[funcName](po) ~= offValue then @@ -2756,9 +3118,10 @@ local function rightFrame() end -- for convenience to generate a choice table for a boolean interface setting - local function booleanSettingChoice(visibleName, funcName) + local function booleanSettingChoice(name, funcName) return { - Name = visibleName, + Name = name, + DisplayName = translations[funcName], ChosenFunction = function() local po = getPlayerOptions() if po[funcName](po) == true then @@ -2789,9 +3152,10 @@ local function rightFrame() } end - local function basicNamedPreferenceChoice(preferenceName, displayName, chosenValue) + local function basicNamedPreferenceChoice(preferenceName, name, chosenValue) return { - Name = displayName, + Name = name, + DisplayName = translations[name], ChosenFunction = function() PREFSMAN:SetPreference(preferenceName, chosenValue) end, @@ -2824,6 +3188,7 @@ local function rightFrame() for _, name in ipairs({...}) do o[#o+1] = { Name = name, + DisplayName = translations[name], } end return o @@ -2876,7 +3241,8 @@ local function rightFrame() }, wheelPosition = themeoption("global", "WheelPosition"), wheelBanners = themeoption("global", "WheelBanners"), - showBackgrounds = themeoption("global", "ShowBackgrounds"), + showBackgrounds = PREFSMAN:GetPreference("ShowBackgrounds"), + showBanners = themeoption("global", "ShowBanners"), useSingleColorBG = themeoption("global", "FallbackToAverageColorBG"), showVisualizer = themeoption("global", "ShowVisualizer"), tipType = themeoption("global", "TipType"), @@ -2891,8 +3257,10 @@ local function rightFrame() fullProgressBar = playeroption("FullProgressBar"), miniProgressBar = playeroption("MiniProgressBar"), judgeCounter = playeroption("JudgeCounter"), - leaderboard = playeroption("leaderboardEnabled"), + leaderboard = playeroption("Leaderboard"), -- off, online, local currentrate, local allrates displayMean = playeroption("DisplayMean"), + displayEWMA = playeroption("DisplayEWMA"), + displayStdDev = playeroption("DisplayStdDev"), measureCounter = playeroption("MeasureCounter"), measureLines = {get = getdataPLAYER("MeasureLines"), set = function(x) setdataPLAYER("MeasureLines", x) THEME:ReloadMetrics() end}, npsDisplay = playeroption("NPSDisplay"), @@ -2905,6 +3273,7 @@ local function rightFrame() laneCover = playeroption("LaneCover"), -- 0 off, 1 sudden, 2 hidden judgmentText = playeroption("JudgmentText"), judgmentTweens = playeroption("JudgmentTweens"), + comboTweens = playeroption("ComboTweens"), comboText = playeroption("ComboText"), comboGlow = playeroption("ComboGlow"), comboLabel = playeroption("ComboLabel"), @@ -3071,14 +3440,6 @@ local function rightFrame() setPlayerOptionsModValueAllLevels("MMod", speed) end end - local function basicNamedOptionDataChoice(optionDataPropertyName, displayName, chosenValue) - return { - Name = displayName, - ChosenFunction = function() - optionData[optionDataPropertyName] = chosenValue - end, - } - end local function optionDataToggleDirections(optionDataPropertyName, trueValue, falseValue) return { Toggle = function() @@ -3124,8 +3485,9 @@ local function rightFrame() local function customizeGameplayButton() return { Name = "Customize Playfield", + DisplayName = translations["CustomizeGameplay"], Type = "Button", - Explanation = "Customize Gameplay elements.", + Explanation = translations["CustomizeGameplayExplanation"], Choices = { { Name = "Customize Playfield", @@ -3158,6 +3520,7 @@ local function rightFrame() -- the names and order of the option pages -- these values must correspond to the keys of optionPageCategoryLists + -- translated by transforming the name to "PageNamePlayer" etc local pageNames = { "Player", "Gameplay", @@ -3172,6 +3535,7 @@ local function rightFrame() -- the values are tables -- the categories of each page in that order -- each category corresponds to a key in optionDefs (must be unique keys -- values of these tables have to be globally unique) -- the options of each category are in the order of the value tables in optionDefs + -- translated by transforming the name to "CategoryEssential Options" etc local optionPageCategoryLists = { Player = { "Essential Options", @@ -3211,12 +3575,14 @@ local function rightFrame() -- OPTION DEFINITION EXAMPLE: --[[ { - Name = "option name" -- display name for the option + Name = "option name" -- internal name for the option + DisplayName = "option name" -- display name for the option Type = "type name" -- determines how to generate the actor to display the choices AssociatedOptions = {"other option name"} -- runs the index getter for these options when a choice is selected Choices = { -- option choice definitions -- each entry is another table -- if no choices are defined, visible choice comes from ChoiceIndexGetter { - Name = "choice1" -- display name for the choice + Name = "choice1" -- internal name for the choice + DisplayName = "choice1" -- display name for the choice ChosenFunction = function() end -- what happens when choice is PICKED (not hovered) }, { @@ -3247,8 +3613,9 @@ local function rightFrame() ["Essential Options"] = { { Name = "Scroll Type", + DisplayName = translations["ScrollType"], Type = "SingleChoice", - Explanation = "XMod - BPM multiplier based scrolling. CMod - Constant scrolling. MMod - BPM based with a max speed.", + Explanation = translations["ScrollTypeExplanation"], AssociatedOptions = { "Scroll Speed", }, @@ -3294,8 +3661,9 @@ local function rightFrame() }, { Name = "Scroll Speed", + DisplayName = translations["ScrollSpeed"], Type = "SingleChoiceModifier", - Explanation = "Change scroll speed value/modifier in increments of 1 or 50.", + Explanation = translations["ScrollSpeedExplanation"], Directions = { Left = function(multiplier) local increment = -1 @@ -3324,8 +3692,9 @@ local function rightFrame() }, { Name = "Scroll Direction", + DisplayName = translations["ScrollDirection"], Type = "SingleChoice", - Explanation = "Direction of note scrolling: up or down.", + Explanation = translations["ScrollDirectionExplanation"], Choices = choiceSkeleton("Upscroll", "Downscroll"), Directions = { Toggle = function() @@ -3349,8 +3718,9 @@ local function rightFrame() }, { Name = "Noteskin", + DisplayName = translations["OptionNoteskin"], Type = "SingleChoice", - Explanation = "Skin of the notes.", + Explanation = translations["OptionNoteskinExplanation"], ChoiceIndexGetter = function() local currentSkinName = getPlayerOptions():NoteSkin() for i, name in ipairs(optionData.noteSkins.names) do @@ -3374,6 +3744,7 @@ local function rightFrame() for i, name in ipairs(skinNames) do o[#o+1] = { Name = name:upper(), + DisplayName = name:upper(), ChosenFunction = function() setPlayerOptionsModValueAllLevels("NoteSkin", name) MESSAGEMAN:Broadcast("UpdateVisibleSkin", {name = name}) @@ -3391,8 +3762,9 @@ local function rightFrame() }, { Name = "Receptor Size", + DisplayName = translations["ReceptorSize"], Type = "SingleChoice", - Explanation = "Size of receptors and notes. 50% Receptor Size may be called 100% Mini.", + Explanation = translations["ReceptorSizeExplanation"], Directions = { Left = function() local sz = optionData["receptorSize"].get() @@ -3413,8 +3785,9 @@ local function rightFrame() }, { Name = "Judge Difficulty", + DisplayName = translations["JudgeDifficulty"], Type = "SingleChoice", - Explanation = "Timing Window Difficulty. Higher is harder. All scores are converted to Judge 4 later.", + Explanation = translations["JudgeDifficultyExplanation"], ChoiceIndexGetter = function() local lowestJudgeDifficulty = 4 return GetTimingDifficulty() - (lowestJudgeDifficulty-1) @@ -3424,6 +3797,7 @@ local function rightFrame() for i = 4, 8 do o[#o+1] = { Name = tostring(i), + DisplayName = tostring(i), ChosenFunction = function() -- set judge local scale = ms.JudgeScalers[i] @@ -3434,6 +3808,7 @@ local function rightFrame() end o[#o+1] = { Name = "Justice", + DisplayName = translations["Justice"], ChosenFunction = function() -- sets j9 local scale = ms.JudgeScalers[9] @@ -3446,8 +3821,9 @@ local function rightFrame() }, { Name = "Mirror", + DisplayName = translations["Mirror"], Type = "SingleChoice", - Explanation = "Horizontally flip Notedata.", + Explanation = translations["MirrorExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = { Toggle = function() @@ -3469,8 +3845,9 @@ local function rightFrame() }, { Name = "Global Offset", + DisplayName = translations["GlobalOffset"], Type = "SingleChoice", - Explanation = "Global Audio Offset in seconds. Negative numbers are early.", + Explanation = translations["GlobalOffsetExplanation"], Directions = preferenceIncrementDecrementDirections("GlobalOffsetSeconds", -5, 5, 0.001), ChoiceIndexGetter = function() return notShit.round(PREFSMAN:GetPreference("GlobalOffsetSeconds"), 3) .. "s" @@ -3478,8 +3855,9 @@ local function rightFrame() }, { Name = "Visual Delay", + DisplayName = translations["VisualDelay"], Type = "SingleChoice", - Explanation = "Visual Note Delay in seconds. May be referred to as Judge Offset. Negative numbers are early.", + Explanation = translations["VisualDelayExplanation"], Directions = preferenceIncrementDecrementDirections("VisualDelaySeconds", -5, 5, 0.001), ChoiceIndexGetter = function() return notShit.round(PREFSMAN:GetPreference("VisualDelaySeconds"), 3) .. "s" @@ -3487,8 +3865,9 @@ local function rightFrame() }, { Name = "Game Mode", + DisplayName = translations["GameMode"], Type = "SingleChoice", - Explanation = "Dance - 3k/4k/8k | Solo - 6k | Pump - 5k/6k/10k | Beat - 5k+1/7k+1/10k+2/14k+2 | Kb7 - 7k | Popn - 5k/9k", + Explanation = translations["GameModeExplanation"], ChoiceIndexGetter = function() for i = 1, #optionData.gameMode.modes do if optionData.gameMode.modes[i] == optionData.gameMode.current then @@ -3502,6 +3881,7 @@ local function rightFrame() for i, name in ipairs(optionData.gameMode.modes) do o[#o+1] = { Name = strCapitalize(name), + DisplayName = strCapitalize(name), ChosenFunction = function() if name == GAMESTATE:GetCurrentGame():GetName() then modsToApplyAtExit["GameMode"] = nil @@ -3521,8 +3901,9 @@ local function rightFrame() }, { Name = "Fail Type", + DisplayName = translations["FailType"], Type = "SingleChoice", - Explanation = "Toggle failure in Gameplay. Setting Fail Off invalidates scores if a fail would have actually occurred.", + Explanation = translations["FailTypeExplanation"], ChoiceIndexGetter = function() local failtypes = FailType local failtype = getPlayerOptions():FailSetting() @@ -3538,6 +3919,7 @@ local function rightFrame() for i, name in ipairs(failtypes) do o[#o+1] = { Name = THEME:GetString("OptionNames", ToEnumShortString(name)), + DisplayName = THEME:GetString("OptionNames", ToEnumShortString(name)), ChosenFunction = function() setPlayerOptionsModValueAllLevels("FailSetting", name) end, @@ -3549,11 +3931,13 @@ local function rightFrame() customizeGameplayButton(), { Name = "Customize Keybinds", + DisplayName = translations["CustomizeKeybinds"], Type = "Button", - Explanation = "Customize Keybinds.", + Explanation = translations["CustomizeKeybindsExplanation"], Choices = { { Name = "Customize Keybinds", + DisplayName = translations["CustomizeKeybindsButton"], ChosenFunction = function() -- activate keybind screen MESSAGEMAN:Broadcast("ShowSettingsAlt", {name = "Customize Keybinds"}) @@ -3563,11 +3947,13 @@ local function rightFrame() }, { Name = "Enter Practice Mode", + DisplayName = translations["PracticeMode"], Type = "Button", - Explanation = "Enter Practice Mode", + Explanation = translations["PracticeModeExplanation"], Choices = { { Name = "Enter Practice Mode", + DisplayName = translations["PracticeModeButton"], ChosenFunction = function() -- activate practice mode -- go into gameplay @@ -3596,8 +3982,9 @@ local function rightFrame() ["Appearance Options"] = { { Name = "Appearance", + DisplayName = translations["Appearance"], Type = "MultiChoice", - Explanation = "Hidden - Notes disappear before receptor. Sudden - Notes appear later than usual. Stealth - Invisible notes. Blink - Notes flash.", + Explanation = translations["AppearanceExplanation"], AssociatedOptions = { "Hidden Offset", "Sudden Offset", @@ -3621,8 +4008,9 @@ local function rightFrame() }, { Name = "Hidden Offset", + DisplayName = translations["HiddenOffset"], Type = "SingleChoiceModifier", - Explanation = "Offset the Hidden position. Hidden hides notes just before they reach the receptors.", + Explanation = translations["HiddenOffsetExplanation"], AssociatedOptions = { "Appearance", }, @@ -3664,8 +4052,9 @@ local function rightFrame() }, { Name = "Sudden Offset", + DisplayName = translations["SuddenOffset"], Type = "SingleChoiceModifier", - Explanation = "Offset the Sudden position. Sudden hides notes until they pass a certain distance across the screen.", + Explanation = translations["SuddenOffsetExplanation"], AssociatedOptions = { "Appearance", }, @@ -3707,8 +4096,9 @@ local function rightFrame() }, { Name = "Perspective", + DisplayName = translations["Perspective"], Type = "SingleChoice", - Explanation = "Controls tilt/skew of the NoteField.", + Explanation = translations["PerspectiveExplanation"], AssociatedOptions = { "Perspective Intensity", }, @@ -3722,30 +4112,35 @@ local function rightFrame() -- setPlayerOptionsModValueAllLevels("Tilt", x) { Name = "Overhead", + DisplayName = translations["Overhead"], ChosenFunction = function() setPlayerOptionsModValueAllLevels("Overhead", true) end, }, { Name = "Incoming", + DisplayName = translations["Incoming"], ChosenFunction = function() setPlayerOptionsModValueAllLevels("Incoming", 1) end, }, { Name = "Space", + DisplayName = translations["Space"], ChosenFunction = function() setPlayerOptionsModValueAllLevels("Space", 1) end, }, { Name = "Hallway", + DisplayName = translations["Hallway"], ChosenFunction = function() setPlayerOptionsModValueAllLevels("Hallway", 1) end, }, { Name = "Distant", + DisplayName = translations["Distant"], ChosenFunction = function() setPlayerOptionsModValueAllLevels("Distant", 1) end, @@ -3767,8 +4162,9 @@ local function rightFrame() }, { Name = "Perspective Intensity", + DisplayName = translations["PerspectiveIntensity"], Type = "SingleChoiceModifier", - Explanation = "Controls the intensity of the tilt/skew of the NoteField.", + Explanation = translations["PerspectiveIntensityExplanation"], Directions = { Left = function(multiplier) local po = getPlayerOptions() @@ -3833,8 +4229,9 @@ local function rightFrame() }, { Name = "Hide Player UI", + DisplayName = translations["HidingModifiers"], Type = "MultiChoice", - Explanation = "Hide certain sets of elements from the Gameplay UI.", + Explanation = translations["HidingModifiersExplanation"], Choices = { floatSettingChoice("Hide Receptors", "Dark", 1, 0), floatSettingChoice("Hide Judgment & Combo", "Blind", 1, 0), @@ -3849,11 +4246,13 @@ local function rightFrame() }, { Name = "Hidenote Judgment", + DisplayName = translations["Hidenote"], Type = "SingleChoice", - Explanation = "Notes must be hit with this judgment or better to disappear.", + Explanation = translations["HidenoteExplanation"], Choices = { { Name = "Miss", + DisplayName = getJudgeStrings("TapNoteScore_Miss"), ChosenFunction = function() PREFSMAN:SetPreference("MinTNSToHideNotes", "Miss") setPlayerOptionsModValueAllLevels("MinTNSToHideNotes", "Miss") @@ -3861,6 +4260,7 @@ local function rightFrame() }, { Name = "Bad", + DisplayName = getJudgeStrings("TapNoteScore_W5"), ChosenFunction = function() PREFSMAN:SetPreference("MinTNSToHideNotes", "W5") setPlayerOptionsModValueAllLevels("MinTNSToHideNotes", "W5") @@ -3868,6 +4268,7 @@ local function rightFrame() }, { Name = "Good", + DisplayName = getJudgeStrings("TapNoteScore_W4"), ChosenFunction = function() PREFSMAN:SetPreference("MinTNSToHideNotes", "W4") setPlayerOptionsModValueAllLevels("MinTNSToHideNotes", "W4") @@ -3875,6 +4276,7 @@ local function rightFrame() }, { Name = "Great", + DisplayName = getJudgeStrings("TapNoteScore_W3"), ChosenFunction = function() PREFSMAN:SetPreference("MinTNSToHideNotes", "W3") setPlayerOptionsModValueAllLevels("MinTNSToHideNotes", "W3") @@ -3882,6 +4284,7 @@ local function rightFrame() }, { Name = "Perfect", + DisplayName = getJudgeStrings("TapNoteScore_W2"), ChosenFunction = function() PREFSMAN:SetPreference("MinTNSToHideNotes", "W2") setPlayerOptionsModValueAllLevels("MinTNSToHideNotes", "W2") @@ -3889,6 +4292,7 @@ local function rightFrame() }, { Name = "Marvelous", + DisplayName = getJudgeStrings("TapNoteScore_W1"), ChosenFunction = function() PREFSMAN:SetPreference("MinTNSToHideNotes", "W1") setPlayerOptionsModValueAllLevels("MinTNSToHideNotes", "W1") @@ -3910,21 +4314,25 @@ local function rightFrame() }, { Name = "Default Centered NoteField", + DisplayName = translations["CenterPlayer1"], Type = "SingleChoice", - Explanation = "Horizontally center the NoteField in Gameplay (Legacy Shortcut).", + Explanation = translations["CenterPlayer1Explanation"], Choices = choiceSkeleton("Yes", "No"), Directions = preferenceToggleDirections("Center1Player", true, false), ChoiceIndexGetter = preferenceToggleIndexGetter("Center1Player", true), }, { Name = "NoteField BG Opacity", + DisplayName = translations["NoteFieldFilter"], Type = "SingleChoice", - Explanation = "Set the opacity of the board behind the NoteField in Gameplay.", + Explanation = translations["NoteFieldFilterExplanation"], ChoiceGenerator = function() local o = {} for i = 0, 10 do -- 11 choices + local nm = notShit.round(i*10,0).."%" o[#o+1] = { - Name = notShit.round(i*10,0).."%", + Name = nm, + DisplayName = nm, ChosenFunction = function() optionData["screenFilter"].set(notShit.round(i / 10, 1)) end, @@ -3933,7 +4341,7 @@ local function rightFrame() return o end, ChoiceIndexGetter = function() - local v = notShit.round(optionData["screenFilter"].get(), 1) + local v = notShit.round(optionData["screenFilter"].get(), 2) local ind = notShit.round(v * 10, 0) + 1 if ind > 0 and ind < 11 then -- this 11 should match the number of choices above return ind @@ -3948,13 +4356,16 @@ local function rightFrame() }, { Name = "Background Brightness", + DisplayName = translations["BGBrightness"], Type = "SingleChoice", - Explanation = "Set the brightness of the background in Gameplay. 0% will disable background loading.", + Explanation = translations["BGBrightnessExplanation"], ChoiceGenerator = function() local o = {} for i = 0, 10 do -- 11 choices + local nm = notShit.round(i*10,0).."%" o[#o+1] = { - Name = notShit.round(i*10,0).."%", + Name = nm, + DisplayName = nm, ChosenFunction = function() PREFSMAN:SetPreference("BGBrightness", notShit.round(i / 10, 1)) end, @@ -3963,9 +4374,9 @@ local function rightFrame() return o end, ChoiceIndexGetter = function() - local v = notShit.round(PREFSMAN:GetPreference("BGBrightness")) + local v = notShit.round(PREFSMAN:GetPreference("BGBrightness"), 2) local ind = notShit.round(v * 10, 0) + 1 - if ind > 0 and ind < 11 then -- this 11 should match the nubmer of choices above + if ind > 0 and ind < 11 then -- this 11 should match the number of choices above return ind else if ind <= 0 then @@ -3978,16 +4389,18 @@ local function rightFrame() }, { Name = "Replay Mod Emulation", + DisplayName = translations["ReplayModEmulation"], Type = "SingleChoice", - Explanation = "Toggle temporarily using compatible mods that replays used when watching them.", + Explanation = translations["ReplayModEmulationExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = preferenceToggleDirections("ReplaysUseScoreMods", true, false), ChoiceIndexGetter = preferenceToggleIndexGetter("ReplaysUseScoreMods", true), }, { Name = "Extra Scroll Mods", + DisplayName = translations["ExtraScrollMods"], Type = "MultiChoice", - Explanation = "Change scroll direction in more interesting ways.", + Explanation = translations["ExtraScrollModsExplanation"], Choices = { floatSettingChoice("Split", "Split", 1, 0), floatSettingChoice("Alternate", "Alternate", 1, 0), @@ -4006,8 +4419,9 @@ local function rightFrame() }, { Name = "Fun Effects", + DisplayName = translations["FunEffects"], Type = "MultiChoice", - Explanation = "Visual scroll mods that are not for practical use.", + Explanation = translations["FunEffectsExplanation"], Choices = { floatSettingChoice("Drunk", "Drunk", 1, 0), floatSettingChoice("Confusion", "Confusion", 1, 0), @@ -4041,8 +4455,9 @@ local function rightFrame() }, { Name = "Acceleration", + DisplayName = translations["Acceleration"], Type = "MultiChoice", - Explanation = "Scroll speed mods usually not for practical use.", + Explanation = translations["AccelerationExplanation"], Choices = { floatSettingChoice("Boost", "Boost", 1, 0), floatSettingChoice("Brake", "Brake", 1, 0), @@ -4068,11 +4483,13 @@ local function rightFrame() ["Invalidating Options"] = { { Name = "Mines", + DisplayName = translations["Mines"], Type = "SingleChoice", - Explanation = "Toggle Mines. Extra Mines will replace entire rows of notes with mines.", + Explanation = translations["MinesExplanation"], Choices = { { Name = "On", + DisplayName = translations["On"], ChosenFunction = function() setPlayerOptionsModValueAllLevels("NoMines", false) setPlayerOptionsModValueAllLevels("Mines", false) @@ -4080,6 +4497,7 @@ local function rightFrame() }, { Name = "Off", + DisplayName = translations["Off"], ChosenFunction = function() setPlayerOptionsModValueAllLevels("NoMines", true) setPlayerOptionsModValueAllLevels("Mines", false) @@ -4087,6 +4505,7 @@ local function rightFrame() }, { Name = "Extra Mines", + DisplayName = translations["ExtraMines"], ChosenFunction = function() setPlayerOptionsModValueAllLevels("NoMines", false) setPlayerOptionsModValueAllLevels("Mines", true) @@ -4109,8 +4528,9 @@ local function rightFrame() }, { Name = "Turn", + DisplayName = translations["Turn"], Type = "MultiChoice", - Explanation = "Modify Notedata by either shifting all notes or randomizing them.", + Explanation = translations["TurnExplanation"], Choices = { booleanSettingChoice("Backwards", "Backwards"), booleanSettingChoice("Left", "Left"), @@ -4118,6 +4538,7 @@ local function rightFrame() booleanSettingChoice("Shuffle", "Shuffle"), booleanSettingChoice("Soft Shuffle", "SoftShuffle"), booleanSettingChoice("Super Shuffle", "SuperShuffle"), + booleanSettingChoice("H-Ran Shuffle", "HRanShuffle"), }, ChoiceIndexGetter = function() local po = getPlayerOptions() @@ -4128,13 +4549,15 @@ local function rightFrame() if po:Shuffle() then o[4] = true end if po:SoftShuffle() then o[5] = true end if po:SuperShuffle() then o[6] = true end + if po:HRanShuffle() then o[7] = true end return o end, }, { Name = "Pattern Transform", + DisplayName = translations["PatternTransform"], Type = "MultiChoice", - Explanation = "Modify Notedata by inserting extra notes to create certain patterns.", + Explanation = translations["PatternTransformExplanation"], Choices = { booleanSettingChoice("Echo", "Echo"), booleanSettingChoice("Stomp", "Stomp"), @@ -4155,8 +4578,9 @@ local function rightFrame() }, { Name = "Hold Transform", + DisplayName = translations["HoldTransform"], Type = "MultiChoice", - Explanation = "Modify holds in Notedata.", + Explanation = translations["HoldTransformExplanation"], Choices = { booleanSettingChoice("Planted", "Planted"), booleanSettingChoice("Floored", "Floored"), @@ -4175,8 +4599,9 @@ local function rightFrame() }, { Name = "Remove", + DisplayName = translations["RemoveMods"], Type = "MultiChoice", - Explanation = "Remove certain notes, patterns, or types of notes.", + Explanation = translations["RemoveModsExplanation"], Choices = { booleanSettingChoice("No Holds", "NoHolds"), booleanSettingChoice("No Rolls", "NoRolls"), @@ -4205,8 +4630,9 @@ local function rightFrame() }, { Name = "Insert", + DisplayName = translations["InsertMods"], Type = "MultiChoice", - Explanation = "Modify Notedata by inserting extra notes to provide a certain feeling.", + Explanation = translations["InsertModsExplanation"], Choices = { booleanSettingChoice("Wide", "Wide"), booleanSettingChoice("Big", "Big"), @@ -4233,55 +4659,81 @@ local function rightFrame() customizeGameplayButton(), { Name = "BPM Display", + DisplayName = translations["BPMDisplay"], Type = "SingleChoice", - Explanation = "Toggle the BPM display.", + Explanation = translations["BPMDisplayExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("bpmDisplay", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("bpmDisplay", true), }, { Name = "Rate Display", + DisplayName = translations["RateDisplay"], Type = "SingleChoice", - Explanation = "Toggle the music rate display.", + Explanation = translations["RateDisplayExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("rateDisplay", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("rateDisplay", true), }, { Name = "Percent Display", + DisplayName = translations["PercentDisplay"], Type = "SingleChoice", - Explanation = "Toggle the wife percent display.", + Explanation = translations["PercentDisplayExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("displayPercent", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("displayPercent", true), }, { Name = "Mean Display", + DisplayName = translations["MeanDisplay"], Type = "SingleChoice", - Explanation = "Toggle the tap mean display.", + Explanation = translations["MeanDisplayExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("displayMean", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("displayMean", true), }, + { + Name = "EWMA Display", + DisplayName = translations["EWMADisplay"], + Type = "SingleChoice", + Explanation = translations["EWMADisplayExplanation"], + Choices = choiceSkeleton("On", "Off"), + Directions = optionDataToggleDirectionsFUNC("displayEWMA", true, false), + ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("displayEWMA", true), + }, + { + Name = "StdDev Display", + DisplayName = translations["StdDevDisplay"], + Type = "SingleChoice", + Explanation = translations["StdDevDisplayExplanation"], + Choices = choiceSkeleton("On", "Off"), + Directions = optionDataToggleDirectionsFUNC("displayStdDev", true, false), + ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("displayStdDev", true), + }, { Name = "Error Bar", + DisplayName = translations["ErrorBar"], Type = "SingleChoice", - Explanation = "Toggle the error bar. Regular displays your recent tap offsets. EWMA displays the exponential mean weighted average of recent taps.", + Explanation = translations["ErrorBarExplanation"], Choices = { { Name = "Regular", + DisplayName = translations["Regular"], ChosenFunction = function() optionData["errorBar"].set(1) end, }, { Name = "EWMA", + DisplayName = translations["EWMA"], ChosenFunction = function() optionData["errorBar"].set(2) end, }, { Name = "Off", + DisplayName = translations["Off"], ChosenFunction = function() optionData["errorBar"].set(0) end, @@ -4300,13 +4752,15 @@ local function rightFrame() }, { Name = "Error Bar Count", + DisplayName = translations["ErrorBarCount"], Type = "SingleChoice", - Explanation = "Choose either how many taps are allowed to show for the Regular error bar, or how many taps are considered for the EWMA error bar.", + Explanation = translations["ErrorBarCountExplanation"], ChoiceGenerator = function() local o = {} for i = 1, 200 do o[#o+1] = { Name = i, + DisplayName = i, ChosenFunction = function() optionData["errorBarCount"].set(i) end, @@ -4325,16 +4779,18 @@ local function rightFrame() }, { Name = "Full Progress Bar", + DisplayName = translations["FullProgressBar"], Type = "SingleChoice", - Explanation = "Toggle the large progress bar.", + Explanation = translations["FullProgressBarExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("fullProgressBar", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("fullProgressBar", true), }, { Name = "Mini Progress Bar", + DisplayName = translations["MiniProgressBar"], Type = "SingleChoice", - Explanation = "Toggle the small progress bar.", + Explanation = translations["MiniProgressBarExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("miniProgressBar", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("miniProgressBar", true), @@ -4342,42 +4798,96 @@ local function rightFrame() { Name = "Leaderboard", + DisplayName = translations["Leaderboard"], Type = "SingleChoice", - Explanation = "Toggle the gameplay leaderboard.", - Choices = choiceSkeleton("On", "Off"), - Directions = optionDataToggleDirectionsFUNC("leaderboard", true, false), - ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("leaderboard", true), + Explanation = translations["LeaderboardExplanation"], + Choices = { + { + Name = "Off", + DisplayName = translations["Off"], + ChosenFunction = function() + optionData["leaderboard"].set(0) + end, + }, + { + Name = "Online", + DisplayName = translations["Online"], + ChosenFunction = function() + optionData["leaderboard"].set(1) + end, + }, + { + Name = "Local", + DisplayName = translations["Local"], + ChosenFunction = function() + optionData["leaderboard"].set(2) + end, + }, + }, + ChoiceIndexGetter = function() + local v = optionData["leaderboard"].get() + return v+1 + end, }, { Name = "Player Info", + DisplayName = translations["PlayerInfo"], Type = "SingleChoice", - Explanation = "Toggle the miscellaneous player info display.", + Explanation = translations["PlayerInfoExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("playerInfo", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("playerInfo", true), }, + { + Name = "Measure Counter", + DisplayName = translations["MeasureCounter"], + Type = "SingleChoice", + Explanation = translations["MeasureCounterExplanation"], + Choices = choiceSkeleton("On", "Off"), + Directions = optionDataToggleDirectionsFUNC("measureCounter", true, false), + ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("measureCounter", true), + }, + { + Name = "Measure Lines", + DisplayName = translations["MeasureLines"], + Type = "SingleChoice", + Explanation = translations["MeasureLinesExplanation"], + Choices = choiceSkeleton("On", "Off"), + Directions = optionDataToggleDirectionsFUNC("measureLines", true, false), + ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("measureLines", true), + }, + }, + -- + ----- + -- GAMEPLAY ELEMENTS P2 + ["Gameplay Elements 2"] = { + customizeGameplayButton(), { Name = "Target Tracker", + DisplayName = translations["TargetTracker"], Type = "SingleChoice", - Explanation = "Toggle the target tracker. This displays your score and points relative to a target.", + Explanation = translations["TargetTrackerExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("targetTracker", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("targetTracker", true), }, { Name = "Target Tracker Mode", + DisplayName = translations["TargetTrackerMode"], Type = "SingleChoice", - Explanation = "Toggle the target tracker mode. PB uses your PB unless it is does not exist. Then it falls back to Goal Percent.", + Explanation = translations["TargetTrackerModeExplanation"], Choices = { { Name = "Personal Best", + DisplayName = translations["PersonalBest"], ChosenFunction = function() optionData["targetTrackerMode"].set(1) end, }, { Name = "Goal Percent", + DisplayName = translations["GoalPercent"], ChosenFunction = function() optionData["targetTrackerMode"].set(0) end, @@ -4394,13 +4904,16 @@ local function rightFrame() }, { Name = "Target Tracker Goal", + DisplayName = translations["TargetTrackerGoal"], Type = "SingleChoice", - Explanation = "Pick a goal percent for the target tracker.", + Explanation = translations["TargetTrackerGoalExplanation"], ChoiceGenerator = function() local o = {} local function cf(i) + local nm = tostring(notShit.round(i, 4)) return { - Name = tostring(notShit.round(i, 4)), + Name = nm, + DisplayName = nm, ChosenFunction = function() optionData["targetTrackerGoal"].set(notShit.round(i, 4)) end } end @@ -4408,7 +4921,7 @@ local function rightFrame() o[#o+1] = cf(i + 50) end -- extra choices to fit grades - o[#o+1] = cf(96.65) -- AA. + o[#o+1] = cf(96.5) -- AA. o[#o+1] = cf(97) o[#o+1] = cf(98) o[#o+1] = cf(99) -- AA: @@ -4431,7 +4944,7 @@ local function rightFrame() return v - 50 + 1 elseif v > 96 then local extra = { - 96.65, + 96.5, 97, 98, 99, @@ -4456,23 +4969,27 @@ local function rightFrame() }, { Name = "Lane Cover", + DisplayName = translations["LaneCover"], Type = "SingleChoice", - Explanation = "Toggle the lane cover. Hidden is on top of the receptors. Sudden is away from the receptors.", + Explanation = translations["LaneCoverExplanation"], Choices = { { Name = "Hidden", + DisplayName = translations["Hidden"], ChosenFunction = function() optionData["laneCover"].set(2) end, }, { Name = "Sudden", + DisplayName = translations["Sudden"], ChosenFunction = function() optionData["laneCover"].set(1) end, }, { Name = "Off", + DisplayName = translations["Off"], ChosenFunction = function() optionData["laneCover"].set(0) end, @@ -4489,96 +5006,92 @@ local function rightFrame() end end, }, - }, - -- - ----- - -- GAMEPLAY ELEMENTS P2 - ["Gameplay Elements 2"] = { - customizeGameplayButton(), { Name = "Judge Counter", + DisplayName = translations["JudgeCounter"], Type = "SingleChoice", - Explanation = "Toggle the judgment counter.", + Explanation = translations["JudgeCounterExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("judgeCounter", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("judgeCounter", true), }, { Name = "Judgment Text", + DisplayName = translations["JudgmentText"], Type = "SingleChoice", - Explanation = "Toggle the judgment text.", + Explanation = translations["JudgmentTextExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("judgmentText", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("judgmentText", true), }, { Name = "Judgment Animations", + DisplayName = translations["JudgmentAnimations"], Type = "SingleChoice", - Explanation = "Toggle the judgment text animations.", + Explanation = translations["JudgmentAnimationsExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("judgmentTweens", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("judgmentTweens", true), }, { Name = "Combo Text", + DisplayName = translations["ComboText"], Type = "SingleChoice", - Explanation = "Toggle the combo text.", + Explanation = translations["ComboTextExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("comboText", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("comboText", true), }, { Name = "Combo Glow", + DisplayName = translations["ComboGlow"], Type = "SingleChoice", - Explanation = "Toggle the extra white glow on the Combo numbers during MFCs and PFCs.", + Explanation = translations["ComboGlowExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("comboGlow", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("comboGlow", true), }, { Name = "Combo Label", + DisplayName = translations["ComboLabel"], Type = "SingleChoice", - Explanation = "Toggle the word 'Combo' as part of the combo text.", + Explanation = translations["ComboLabelExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("comboLabel", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("comboLabel", true), }, { - Name = "Combo-Breaker Highlights", + Name = "Combo Animations", + DisplayName = translations["ComboTweens"], Type = "SingleChoice", - Explanation = "Toggle showing which column a combo breaker occurs.", + Explanation = translations["ComboTweensExplanation"], Choices = choiceSkeleton("On", "Off"), - Directions = optionDataToggleDirectionsFUNC("cbHighlight", true, false), - ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("cbHighlight", true), + Directions = optionDataToggleDirectionsFUNC("comboTweens", true, false), + ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("comboTweens", true), }, { - Name = "Measure Counter", - Type = "SingleChoice", - Explanation = "Toggle the measure counter. This shows up for longer runs of relatively high NPS.", - Choices = choiceSkeleton("On", "Off"), - Directions = optionDataToggleDirectionsFUNC("measureCounter", true, false), - ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("measureCounter", true), - }, - { - Name = "Measure Lines", + Name = "Combo-Breaker Highlights", + DisplayName = translations["CBHighlights"], Type = "SingleChoice", - Explanation = "Toggle showing a line on the NoteField for every measure.", + Explanation = translations["CBHighlightsExplanation"], Choices = choiceSkeleton("On", "Off"), - Directions = optionDataToggleDirectionsFUNC("measureLines", true, false), - ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("measureLines", true), + Directions = optionDataToggleDirectionsFUNC("cbHighlight", true, false), + ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("cbHighlight", true), }, { Name = "NPS Display", + DisplayName = translations["NPSDisplay"], Type = "SingleChoice", - Explanation = "Toggle the notes per second display. Displays just NPS and max NPS.", + Explanation = translations["NPSDisplayExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("npsDisplay", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("npsDisplay", true), }, { Name = "NPS Graph", + DisplayName = translations["NPSGraph"], Type = "SingleChoice", - Explanation = "Toggle the notes per second graph. Displays the NPS over time.", + Explanation = translations["NPSGraphExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("npsGraph", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("npsGraph", true), @@ -4590,8 +5103,9 @@ local function rightFrame() ["Global Options"] = { { Name = "Language", + DisplayName = translations["Language"], Type = "SingleChoice", - Explanation = "Modify the game language.", + Explanation = translations["LanguageExplanation"], ChoiceIndexGetter = function() for i, l in ipairs(optionData.language.list) do if l == optionData.language.current then @@ -4605,6 +5119,7 @@ local function rightFrame() for i, l in ipairs(optionData.language.list) do o[#o+1] = { Name = l:upper(), + DisplayName = l:upper(), ChosenFunction = function() if l == THEME:GetCurLanguage() then modsToApplyAtExit["Language"] = nil @@ -4624,8 +5139,9 @@ local function rightFrame() }, { Name = "Theme", + DisplayName = translations["Theme"], Type = "SingleChoice", - Explanation = "Change the overall skin of the game.", + Explanation = translations["ThemeExplanation"], ChoiceIndexGetter = function() local cur = optionData.pickedTheme for i, name in ipairs(THEME:GetSelectableThemeNames()) do @@ -4638,6 +5154,7 @@ local function rightFrame() for _, name in ipairs(THEME:GetSelectableThemeNames()) do o[#o+1] = { Name = name, + DisplayName = name, ChosenFunction = function() if name == THEME:GetCurThemeName() then modsToApplyAtExit["Theme"] = nil @@ -4657,8 +5174,9 @@ local function rightFrame() }, { Name = "Display Mode", + DisplayName = translations["DisplayMode"], Type = "SingleChoice", - Explanation = "Change the game display mode. Borderless requires that you select your native fullscreen resolution.", + Explanation = translations["DisplayModeExplanation"], AssociatedOptions = { "Aspect Ratio", "Display Resolution", @@ -4671,6 +5189,7 @@ local function rightFrame() Choices = { { Name = "Windowed", + DisplayName = translations["Windowed"], ChosenFunction = function() PREFSMAN:SetPreference("Windowed", true) PREFSMAN:SetPreference("FullscreenIsBorderlessWindow", false) @@ -4694,6 +5213,7 @@ local function rightFrame() }, { Name = "Fullscreen", + DisplayName = translations["Fullscreen"], ChosenFunction = function() PREFSMAN:SetPreference("Windowed", false) PREFSMAN:SetPreference("FullscreenIsBorderlessWindow", false) @@ -4719,6 +5239,7 @@ local function rightFrame() -- funny thing about this preference is that it doesnt force fullscreen -- so you have to pick the right resolution for it to work Name = "Borderless", + DisplayName = translations["Borderless"], ChosenFunction = function() PREFSMAN:SetPreference("Windowed", false) PREFSMAN:SetPreference("FullscreenIsBorderlessWindow", true) @@ -4755,8 +5276,9 @@ local function rightFrame() }, { Name = "Aspect Ratio", + DisplayName = translations["AspectRatio"], Type = "SingleChoice", - Explanation = "Change the game aspect ratio.", + Explanation = translations["AspectRatioExplanation"], AssociatedOptions = { "Display Resolution", "Refresh Rate", @@ -4794,8 +5316,9 @@ local function rightFrame() }, { Name = "Display Resolution", + DisplayName = translations["DisplayResolution"], Type = "SingleChoice", - Explanation = "Change the game display resolution.", + Explanation = translations["DisplayResolutionExplanation"], AssociatedOptions = { "Aspect Ratio", "Refresh Rate", @@ -4838,8 +5361,9 @@ local function rightFrame() }, { Name = "Refresh Rate", + DisplayName = translations["RefreshRate"], Type = "SingleChoice", - Explanation = "Change the game refresh rate. Set to default in most cases. Changes the refresh rate, but not the FPS cap. Only applies in exclusive fullscreen.", + Explanation = translations["RefreshRateExplanation"], AssociatedOptions = { "Aspect Ratio", "Display Resolution", @@ -4874,8 +5398,9 @@ local function rightFrame() }, { Name = "Display Color Depth", + DisplayName = translations["ColorDepth"], Type = "SingleChoice", - Explanation = "Change the color depth of the game according to your display. Usually not worth changing.", + Explanation = translations["ColorDepthExplanation"], Choices = { basicNamedPreferenceChoice("DisplayColorDepth", "16bit", 16), basicNamedPreferenceChoice("DisplayColorDepth", "32bit", 32), @@ -4899,11 +5424,13 @@ local function rightFrame() }, { Name = "Force High Resolution Textures", + DisplayName = translations["HighResTextures"], Type = "SingleChoice", - Explanation = "Force high resolution textures. Turning this off disables the (doubleres) image tag.", + Explanation = translations["HighResTexturesExplanation"], Choices = { { Name = "Auto", + DisplayName = translations["Automatic"], ChosenFunction = function() local v = "HighResolutionTextures_Auto" PREFSMAN:SetPreference("HighResolutionTextures", v) @@ -4920,6 +5447,7 @@ local function rightFrame() }, { Name = "Force On", + DisplayName = translations["ForceOn"], ChosenFunction = function() local v = "HighResolutionTextures_ForceOn" PREFSMAN:SetPreference("HighResolutionTextures", v) @@ -4936,6 +5464,7 @@ local function rightFrame() }, { Name = "Force Off", + DisplayName = translations["ForceOff"], ChosenFunction = function() local v = "HighResolutionTextures_ForceOff" PREFSMAN:SetPreference("HighResolutionTextures", v) @@ -4960,13 +5489,15 @@ local function rightFrame() }, { Name = "Texture Resolution", + DisplayName = translations["TextureResolution"], Type = "SingleChoice", - Explanation = "Modify general texture resolution. Lower number will lower quality but may increase FPS.", + Explanation = translations["TextureResolutionExplanation"], -- FUN FACT YOU CAN PUT ANY NUMBER IN FOR THESE -- AS LONG AS IT ISNT INSANE OR 0 IT SHOULD WORK Choices = { { Name = "256", + DisplayName = "256", ChosenFunction = function() local v = 256 PREFSMAN:SetPreference("MaxTextureResolution", v) @@ -4983,6 +5514,7 @@ local function rightFrame() }, { Name = "512", + DisplayName = "512", ChosenFunction = function() local v = 512 PREFSMAN:SetPreference("MaxTextureResolution", v) @@ -4999,6 +5531,7 @@ local function rightFrame() }, { Name = "1024", + DisplayName = "1024", ChosenFunction = function() local v = 1024 PREFSMAN:SetPreference("MaxTextureResolution", v) @@ -5015,6 +5548,7 @@ local function rightFrame() }, { Name = "2048", + DisplayName = "2048", ChosenFunction = function() local v = 2048 PREFSMAN:SetPreference("MaxTextureResolution", v) @@ -5076,11 +5610,13 @@ local function rightFrame() ]] { Name = "VSync", + DisplayName = translations["VSync"], Type = "SingleChoice", - Explanation = "Restrict the game refresh rate and FPS to the refresh rate you have set.", + Explanation = translations["VSyncExplanation"], Choices = { { Name = "On", + DisplayName = translations["On"], ChosenFunction = function() local v = true PREFSMAN:SetPreference("Vsync", v) @@ -5097,6 +5633,7 @@ local function rightFrame() }, { Name = "Off", + DisplayName = translations["Off"], ChosenFunction = function() local v = false PREFSMAN:SetPreference("Vsync", v) @@ -5119,28 +5656,49 @@ local function rightFrame() }, { Name = "Fast Note Rendering", + DisplayName = translations["FastNoteRendering"], Type = "SingleChoice", - Explanation = "Optimize gameplay note rendering. Disable snap based noteskin features (not snaps themselves). Major boost to FPS.", + Explanation = translations["FastNoteRenderingExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = preferenceToggleDirections("FastNoteRendering", true, false), ChoiceIndexGetter = preferenceToggleIndexGetter("FastNoteRendering", true), }, { Name = "Show Stats", + DisplayName = translations["ShowStats"], Type = "SingleChoice", - Explanation = "Show FPS display on screen.", + Explanation = translations["ShowStatsExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = preferenceToggleDirections("ShowStats", true, false), ChoiceIndexGetter = preferenceToggleIndexGetter("ShowStats", true), }, { Name = "Tap Glow", + DisplayName = translations["TapGlow"], Type = "SingleChoice", - Explanation = "Show a white flash before notes disappear when using Hidden or Sudden.", + Explanation = translations["TapGlowExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = preferenceToggleDirections("NoGlow", false, true), ChoiceIndexGetter = preferenceToggleIndexGetter("NoGlow", false), - } + }, + { + Name = "Show Backgrounds", + DisplayName = translations["ShowBGs"], + Type = "SingleChoice", + Explanation = translations["ShowBGsExplanation"], + Choices = choiceSkeleton("Yes", "No"), + Directions = preferenceToggleDirections("ShowBackgrounds", true, false), + ChoiceIndexGetter = preferenceToggleIndexGetter("ShowBackgrounds", true), + }, + { + Name = "Show Banners", + DisplayName = translations["ShowBanners"], + Type = "SingleChoice", + Explanation = translations["ShowBannersExplanation"], + Choices = choiceSkeleton("Yes", "No"), + Directions = optionDataToggleDirectionsFUNC("showBanners", true, false), + ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("showBanners", true), + }, }, -- ----- @@ -5148,96 +5706,99 @@ local function rightFrame() ["Theme Options"] = { { Name = "Music Wheel Position", + DisplayName = translations["MusicWheelPosition"], Type = "SingleChoice", - Explanation = "Set the side of the screen for the music wheel.", + Explanation = translations["MusicWheelPositionExplanation"], Choices = choiceSkeleton("Left", "Right"), Directions = optionDataToggleDirectionsFUNC("wheelPosition", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("wheelPosition", true), }, { Name = "Music Wheel Banners", + DisplayName = translations["MusicWheelBanners"], Type = "SingleChoice", - Explanation = "Toggle the banners on the music wheel.", + Explanation = translations["MusicWheelBannersExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("wheelBanners", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("wheelBanners", true), }, { Name = "Video Banners", + DisplayName = translations["VideoBanners"], Type = "SingleChoice", - Explanation = "Toggle allowing video banners to play at all on the wheel and other locations in music select.", + Explanation = translations["VideoBannersExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("videoBanners", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("videoBanners", true), }, - { - Name = "Show Backgrounds", - Type = "SingleChoice", - Explanation = "Toggle showing backgrounds everywhere.", - Choices = choiceSkeleton("Yes", "No"), - Directions = optionDataToggleDirectionsFUNC("showBackgrounds", true, false), - ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("showBackgrounds", true), - }, { Name = "BG Fallback to Banner Color", + DisplayName = translations["BGBannerColor"], Type = "SingleChoice", - Explanation = "Toggle using the average color of the pack or song banner when the background is not available. Only applies to music select.", + Explanation = translations["BGBannerColorExplanation"], Choices = choiceSkeleton("Yes", "No"), Directions = optionDataToggleDirectionsFUNC("useSingleColorBG", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("useSingleColorBG", true), }, { Name = "Allow Background Changes", + DisplayName = translations["AllowBGChanges"], Type = "SingleChoice", - Explanation = "Toggle gameplay backgrounds changing.", + Explanation = translations["AllowBGChangesExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("allowBGChanges", false, true), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("allowBGChanges", false), }, { Name = "Easter Eggs & Toasties", + DisplayName = translations["EasterEggs"], Type = "SingleChoice", - Explanation = "Toggle showing secret jokes and toasties.", + Explanation = translations["EasterEggsExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = preferenceToggleDirections("EasterEggs", true, false), ChoiceIndexGetter = preferenceToggleIndexGetter("EasterEggs", true), }, { Name = "Music Visualizer", + DisplayName = translations["Visualizer"], Type = "SingleChoice", - Explanation = "Toggle showing the visualizer in the song select screen.", + Explanation = translations["VisualizerExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = optionDataToggleDirectionsFUNC("showVisualizer", true, false), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("showVisualizer", true), }, { Name = "Mid Grades", + DisplayName = translations["MidGrades"], Type = "SingleChoice", - Explanation = "Toggle showing the grades in between the major grades. Requires game restart.", + Explanation = translations["MidGradesExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = preferenceToggleDirections("UseMidGrades", true, false), ChoiceIndexGetter = preferenceToggleIndexGetter("UseMidGrades", true), }, { Name = "SSRNorm Sort", + DisplayName = translations["SSRNorm"], Type = "SingleChoice", - Explanation = "Toggle automatically sorting by and defaulting to the SSRNorm globally. The SSRNorm is the Judge 4 value of a highscore. Requires game restart.", + Explanation = translations["SSRNormExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = preferenceToggleDirections("SortBySSRNormPercent", true, false), ChoiceIndexGetter = preferenceToggleIndexGetter("SortBySSRNormPercent", true), }, { Name = "Show Lyrics", + DisplayName = translations["ShowLyrics"], Type = "SingleChoice", - Explanation = "Toggle showing lyrics for songs which contain compatible .lrc files.", + Explanation = translations["ShowLyricsExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = preferenceToggleDirections("ShowLyrics", true, false), ChoiceIndexGetter = preferenceToggleIndexGetter("ShowLyrics", true), }, { Name = "Transliteration", + DisplayName = translations["Transliteration"], Type = "SingleChoice", - Explanation = "Toggle showing author-defined translations on song metadata fields.", + Explanation = translations["TransliterationExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = { Toggle = function() @@ -5253,21 +5814,25 @@ local function rightFrame() }, { Name = "Tip Type", + DisplayName = translations["TipType"], Type = "SingleChoice", - Explanation = "Change the quips shown at the bottom of the evaluation screen.", + Explanation = translations["TipTypeExplanation"], Choices = choiceSkeleton("Tips", "Quotes"), Directions = optionDataToggleDirectionsFUNC("tipType", 1, 2), ChoiceIndexGetter = optionDataToggleIndexGetterFUNC("tipType", 1), }, { Name = "Set BG Fit Mode", + DisplayName = translations["BGFit"], Type = "SingleChoice", - Explanation = "Change the cropping strategy of background images.", + Explanation = translations["BGFitExplanation"], ChoiceGenerator = function() local o = {} for _, fit in ipairs(BackgroundFitMode) do + local nm = THEME:GetString("ScreenSetBGFit", ToEnumShortString(fit)) o[#o+1] = { - Name = THEME:GetString("ScreenSetBGFit", ToEnumShortString(fit)), + Name = nm, + DisplayName = nm, ChosenFunction = function() PREFSMAN:SetPreference("BackgroundFitMode", ToEnumShortString(fit)) end, @@ -5287,11 +5852,13 @@ local function rightFrame() }, { Name = "Color Config", + DisplayName = translations["ColorConfig"], Type = "Button", - Explanation = "Modify the colors of this theme.", + Explanation = translations["ColorConfigExplanation"], Choices = { { Name = "Color Config", + DisplayName = translations["ColorConfigButton"], ChosenFunction = function() -- activate color config screen MESSAGEMAN:Broadcast("ShowSettingsAlt", {name = "Color Config"}) @@ -5301,11 +5868,13 @@ local function rightFrame() }, { Name = "Asset Settings", + DisplayName = translations["AssetSettings"], Type = "Button", - Explanation = "Set your avatar, judgments, and toasty.", + Explanation = translations["AssetSettingsExplanation"], Choices = { { Name = "Asset Settings", + DisplayName = translations["AssetSettingsButton"], ChosenFunction = function() -- activate asset settings screen MESSAGEMAN:Broadcast("PlayerInfoFrameTabSet", {tab = "AssetSettings", prevScreen = "Settings"}) @@ -5320,8 +5889,9 @@ local function rightFrame() ["Sound Options"] = { { Name = "Volume", + DisplayName = translations["Volume"], Type = "SingleChoice", - Explanation = "All sound volume.", + Explanation = translations["VolumeExplanation"], Directions = { Left = function() local x = PREFSMAN:GetPreference("SoundVolume") @@ -5342,35 +5912,40 @@ local function rightFrame() }, { Name = "Menu Sounds", + DisplayName = translations["MenuSounds"], Type = "SingleChoice", - Explanation = "Toggle sounds on menu items.", + Explanation = translations["MenuSoundsExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = preferenceToggleDirections("MuteActions", true, false), ChoiceIndexGetter = preferenceToggleIndexGetter("MuteActions", false), }, { Name = "Mine Sounds", + DisplayName = translations["MineSounds"], Type = "SingleChoice", - Explanation = "Toggle sounds for mine explosions.", + Explanation = translations["MineSoundsExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = preferenceToggleDirections("EnableMineHitSound", true, false), ChoiceIndexGetter = preferenceToggleIndexGetter("EnableMineHitSound", true), }, { Name = "Pitch on Rates", + DisplayName = translations["PitchRates"], Type = "SingleChoice", - Explanation = "Toggle pitch changes for songs when using rates.", + Explanation = translations["PitchRatesExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = preferenceToggleDirections("EnablePitchRates", true, false), ChoiceIndexGetter = preferenceToggleIndexGetter("EnablePitchRates", true), }, { Name = "Calibrate Audio Sync", + DisplayName = translations["CalibrateAudioSync"], Type = "Button", - Explanation = "Calibrate the audio sync for the entire game.", + Explanation = translations["CalibrateAudioSyncExplanation"], Choices = { { Name = "Calibrate Audio Sync", + DisplayName = translations["CalibrateAudioSyncButton"], ChosenFunction = function() -- go to machine sync screen SCUFF.screenAfterSyncMachine = SCREENMAN:GetTopScreen():GetName() @@ -5388,24 +5963,27 @@ local function rightFrame() ["Input Options"] = { { Name = "Back Delayed", + DisplayName = translations["BackDelayed"], Type = "SingleChoice", - Explanation = "Modify the behavior of the back button in gameplay.", + Explanation = translations["BackDelayedExplanation"], Choices = choiceSkeleton("Hold", "Instant"), Directions = preferenceToggleDirections("DelayedBack", true, false), ChoiceIndexGetter = preferenceToggleIndexGetter("DelayedBack", true), }, { Name = "Hold Start to Give Up", + DisplayName = translations["StartGiveUp"], Type = "SingleChoice", - Explanation = "In Gameplay, allow holding Start to fail after holding it for a few seconds.", + Explanation = translations["StartGiveUpExplanation"], Choices = choiceSkeleton("On", "Off"), Directions = preferenceToggleDirections("AllowStartToGiveUp", true, false), ChoiceIndexGetter = preferenceToggleIndexGetter("AllowStartToGiveUp", true), }, { Name = "Input Debounce Time", + DisplayName = translations["Debounce"], Type = "SingleChoice", - Explanation = "Set the amount of time required between each repeated input.", + Explanation = translations["DebounceExplanation"], Directions = preferenceIncrementDecrementDirections("InputDebounceTime", 0, 0.2, 0.001), ChoiceIndexGetter = function() return notShit.round(PREFSMAN:GetPreference("InputDebounceTime"), 3) .. "s" @@ -5413,11 +5991,13 @@ local function rightFrame() }, { Name = "Test Input", + DisplayName = translations["TestInput"], Type = "Button", - Explanation = "Enter a screen to test all input devices.", + Explanation = translations["TestInputExplanation"], Choices = { { Name = "Test Input", + DisplayName = translations["TestInputButton"], ChosenFunction = function() -- go to test input screen SCUFF.screenAfterSyncMachine = SCREENMAN:GetTopScreen():GetName() @@ -5434,11 +6014,13 @@ local function rightFrame() ["Profile Options"] = { { Name = "Create Profile", + DisplayName = translations["CreateProfile"], Type = "Button", - Explanation = "Create a new profile.", + Explanation = translations["CreateProfileExplanation"], Choices = { { Name = "Create Profile", + DisplayName = translations["CreateProfileButton"], ChosenFunction = function() -- make a profile -- make profile, rename new profile @@ -5450,11 +6032,13 @@ local function rightFrame() }, { Name = "Rename Profile", + DisplayName = translations["RenameProfile"], Type = "Button", - Explanation = "Rename an existing profile.", + Explanation = translations["RenameProfileExplanation"], Choices = { { Name = "Rename Profile", + DisplayName = translations["RenameProfileButton"], ChosenFunction = function() -- rename a profile renameProfileDialogue(GetPlayerOrMachineProfile(PLAYER_1)) @@ -6363,12 +6947,12 @@ local function rightFrame() if optionDef ~= nil then self:x(0) - txt:settext(optionDef.Name) + txt:settext(optionDef.DisplayName) txt:maxwidth(actuals.OptionTextWidth / optionTitleTextSize - textZoomFudge) elseif categoryDef ~= nil then local newx = actuals.OptionBigTriangleWidth + actuals.OptionTextBuffer / 2 self:x(newx) - txt:settext(categoryDef.Name) + txt:settext(translations["Category"..categoryDef.Name]) txt:maxwidth((actuals.OptionTextWidth - newx) / optionTitleTextSize - textZoomFudge) else txt:settext("") @@ -6928,7 +7512,7 @@ local function rightFrame() local choiceIndex = n + (rowHandle.choicePage-1) * maxChoicesVisibleMultiChoice local choice = optionDef.Choices[choiceIndex] if choice ~= nil then - txt:settext(choice.Name) + txt:settext(choice.DisplayName) else txt:settext("") end @@ -6942,7 +7526,7 @@ local function rightFrame() txt:settext(currentChoiceSelection) elseif optionDef.Choices ~= nil then -- choices present means the getter supplies the choice index that contains the information - txt:settext(optionDef.Choices[currentChoiceSelection].Name) + txt:settext(optionDef.Choices[currentChoiceSelection].DisplayName) else txt:settext("INVALID CONTACT DEVELOPER") end @@ -7152,7 +7736,7 @@ local function rightFrame() self:x((actuals.RightWidth / #pageNames) * (i-1) + (actuals.RightWidth / #pageNames / 2)) txt:zoom(choiceTextSize) txt:maxwidth(actuals.RightWidth / #pageNames / choiceTextSize - textZoomFudge) - txt:settext(pageNames[i]) + txt:settext(translations["PageName"..pageNames[i]]) self:playcommand("ColorConfigUpdated") bg:zoomto(actuals.RightWidth / #pageNames, actuals.TopLipHeight) end, diff --git a/Themes/Rebirth/Graphics/NoteField cover.lua b/Themes/Rebirth/Graphics/NoteField cover.lua index 27d3bc12c8..64ef8c2bac 100644 --- a/Themes/Rebirth/Graphics/NoteField cover.lua +++ b/Themes/Rebirth/Graphics/NoteField cover.lua @@ -45,7 +45,7 @@ end local function getMaxDisplayBPM() local steps = GAMESTATE:GetCurrentSteps() if steps:GetDisplayBPMType() ~= "DisplayBPM_Random" then - return steps:GetDisplayBpms()[2] + return steps:GetDisplayBpms(false)[2] else return steps:GetTimingData():GetActualBPM()[2] end diff --git a/Themes/Rebirth/Graphics/Player combo/default.lua b/Themes/Rebirth/Graphics/Player combo/default.lua index d5709ac958..1855216351 100644 --- a/Themes/Rebirth/Graphics/Player combo/default.lua +++ b/Themes/Rebirth/Graphics/Player combo/default.lua @@ -2,10 +2,14 @@ local c local enabledCombo = playerConfig:get_data().ComboText local enabledLabel = playerConfig:get_data().ComboLabel local enableGlow = playerConfig:get_data().ComboGlow +local animateCombo = playerConfig:get_data().ComboTweens -local function arbitraryComboZoom(value) - c.Label:zoom(value) - c.Number:zoom(value - 0.1) +local function numberZoom() + return math.max((MovableValues.ComboZoom * 1.25) - 0.1, 0) +end + +local function labelZoom() + return math.max(MovableValues.ComboZoom * 1.25, 0) end local ShowComboAt = THEME:GetMetric("Combo", "ShowComboAt") @@ -15,6 +19,20 @@ local pfcNumbers = getComboColor("PerfFullCombo") local fcNumbers = getComboColor("FullCombo") local regNumbers = getComboColor("RegularCombo") +local Pulse = function(self, param) + self:stoptweening() + self:zoom(1.125 * param.Zoom * numberZoom()) + self:linear(0.05) + self:zoom(param.Zoom * numberZoom()) +end + +local PulseLabel = function(self, param) + self:stoptweening() + self:zoom(1.125 * param.LabelZoom * labelZoom()) + self:linear(0.05) + self:zoom(param.LabelZoom * labelZoom()) +end + local translated_combo = "Combo"--THEME:GetString("ScreenGameplay", "ComboText") local t = Def.ActorFrame { @@ -39,7 +57,8 @@ local t = Def.ActorFrame { end, SetUpMovableValuesMessageCommand = function(self) self:xy(MovableValues.ComboX, MovableValues.ComboY) - arbitraryComboZoom(MovableValues.ComboZoom * 1.25) + c.Label:zoom(labelZoom()) + c.Number:zoom(numberZoom()) end, ComboCommand = function(self, param) local iCombo = param.Combo @@ -87,6 +106,18 @@ local t = Def.ActorFrame { c.Label:diffuse(Color("Red")) c.Label:diffusebottomedge(color("0.5,0,0,1")) end + + if animateCombo then + local lb = 0.9 + local ub = 1.1 + local maxcombo = 100 + param.LabelZoom = scale( iCombo, 0, maxcombo, lb, ub ) + param.LabelZoom = clamp( param.LabelZoom, lb, ub ) + param.Zoom = scale( iCombo, 0, maxcombo, lb, ub ) + param.Zoom = clamp( param.Zoom, lb, ub ) + Pulse(c.Number, param) + PulseLabel(c.Label, param) + end end, Def.Quad { -- not normally visible but acts as a way for customize gameplay to hook into the combo size diff --git a/Themes/Rebirth/Languages/en.ini b/Themes/Rebirth/Languages/en.ini index 799448872e..58b356ecd3 100644 --- a/Themes/Rebirth/Languages/en.ini +++ b/Themes/Rebirth/Languages/en.ini @@ -1,6 +1,42 @@ +[AssetSettings] +Title=Asset Settings +HoveredItem=Hovered +SelectedItem=Selected +ToastyPageDisplay=Toasty +AvatarPageDisplay=Avatar +JudgmentPageDisplay=Judgment + +# distinct from the PackDownloader +[BundleDownloader] +Bundle=Bundle +Exit=Exit +Megabytes=MB +KilobytesPerSecond=KB/s +Downloading=Downloading +PacksRemaining=packs remaining +WelcomeInstruction=Welcome to Etterna!\nLet's start by installing some songs. Click the button that corresponds to your skill level and the installation will proceed automatically. +DisconnectedAlert=Server pack listing is empty.\nIs the API down?\nIs your network connection down?\nYou may have to install songs manually. +Novice=Novice +NoviceDescription=A bundle aimed at people who are entirely new to rhythm games.\nMostly single notes throughout the song and very little pattern complexity. +Beginner=Beginner +BeginnerDescription=A bundle for those who have formed some muscle memory.\nJumps (2 note chords) are introduced; some technical patterns start to appear. +Intermediate=Intermediate +IntermediateDescription=A bundle for players who can confidently play complex patterns.\nJumpstream/handstream, very technical patterns, and jacks are common. +Advanced=Advanced +AdvancedDescription=A bundle for advanced players.\nDumps are introduced. Very fast patterns in stamina intensive and complex files. +Expert=Expert +ExpertDescription=A bundle for veterans.\nSome of the hardest songs the game has to offer. Nothing is off-limits. + [Common] WindowTitle=Etterna: Rebirth +[ChartPreview] +CloseChartPreview=Exit + +[ChordDensityGraph] +NPS=NPS +BPM=BPM + [ClearTypes] MFC=MFC WF=WF @@ -16,6 +52,38 @@ Failed=Failed Invalid=Invalid No Play=No Play +[Header] +LogOut=Log out +LogIn=Log in +Plays=plays +ArrowsSmashed=arrows smashed +PlayTime=playtime +PlayerRating=Player Rating +PlayerRatings=Player Ratings +OfflineRating=Offline +OnlineRating=Online +Exit=Exit +Settings=Settings +Help=Help +Downloads=Downloads +Random=Random +Search=Search +DownloadingPacks=Downloading +QueuedPacks=Queued +UploadPercent=Score Upload Progress + +[OffsetPlot] +StandardDeviation=Std. Dev +Mean=Mean +Time=Time +Milliseconds=ms +Late=Late +Early=Early +Instructions=Up/Down for column highlights +CurrentColumnHighlights=Now +UsingReprioritized=Using Reprioritized Offsets + +# legacy option names [OptionNames] SetPercent=Set Percent PersonalBest=Personal Best @@ -23,7 +91,7 @@ EWMA=EWMA NPSDisplay=NPS Display NPSGraph=NPS Graph - +# legacy option titles [OptionTitles] ReceptorSize = Receptor Size CustomizeGameplay= Customize Gameplay @@ -34,6 +102,7 @@ JudgmentText=Judgment Text JudgmentAnimations=Judgment Animations ComboText=Combo Text ComboLabel=Combo Label +ComboTweens=Combo Animations DisplayPercent = Current Percent TargetTracker = Goal Tracker TargetGoal = Tracker Goal @@ -47,6 +116,7 @@ MiniProgressBar = Mini Progressbar Leaderboard = Leaderboard NPSDisplay=NPS Display +# legacy option explanations [OptionExplanations] ReceptorSize = Scale the size of the receptors and notes. This will also indirectly scale your scrolling speed. CustomizeGameplay= While active, allows you to reposition and resize elements on the gameplay screen to your liking. Any changes will persist through version updates. @@ -57,6 +127,7 @@ JudgmentText=Toggle whether or not to show the Judgment. JudgmentAnimations=Toggle judgment animations. ComboText=Toggle whether or not to show the combo. ComboLabel=Toggle whether or not to show the combo text next to the number. +ComboTweens=Toggle animations for the combo text. DisplayPercent = Displays the current percent for your score. TargetTracker = Enable Goal Tracker. Displays the differential between your current score and 93% of the maximum score obtainable, or pits you against your personal best. TargetGoal = Set the percentage goal for the target tracker. @@ -71,12 +142,436 @@ FullProgressBar = Displays your progress through the song as well as song title. MiniProgressBar = Display a smaller, less intrusive, more accessible version of the progress bar placed above the combo text. NPSDisplay=Toggle whether to display a flying average NPS display. The time window can be set at Theme Options. +[PackDownloader] +Title=Pack Downloader +Back=Back +BundleSelect=Bundle Select +CancelAll=Cancel All Downloads +Expanded=Expanded +Novice=Novice +Beginner=Beginner +Intermediate=Intermediate +Advanced=Advanced +Expert=Expert +Megabytes=MB +Cancel=Cancel +Queued=Queued +HeaderName=Name +HeaderAverage=Avg +HeaderSize=Size +DownloadBundle=Download Bundle +DownloadBundleMirrored=Download Bundle (Mirror) +DownloadPack=Download Pack +DownloadPackMirrored=Download Pack (Mirror) +AlreadyInstalled=Already Installed +CurrentlyDownloading=Currently Downloading + +[ScreenEvaluation] +Title=Results +ReplayTitle=Replay Results +Mean=Mean +StandardDeviation=Sd +Largest=Largest +LeftCBs=Left CBs +MiddleCBs=Middle CBs +RightCBs=Right CBs +CBsPerColumn=CBs Per Column +Column=Column +Justice=Justice +NoReplayData=No Replay Data +You=You +LastScore=Last Score +NoLocalScoresRecorded=No local scores recorded +ChartUnranked=Chart is unranked +FetchingScores=Fetching scores... +NoOnlineScoresRecorded=No online scores recorded +ShowingXXofXScoresFormatStr=Showing %d-%d of %d scores +Local=Local +Online=Online +AllScores=All Scores +TopScores=Top Scores +CurrentRate=Current Rate +AllRates=All Rates + [ScreenGameplay] ButtonPlay=Play ButtonPause=Pause ButtonFastForward=Fast Forward ButtonRewind=Rewind -InvalidMods=INVALID MODIFIERS +Results=Results +Exit=Exit +MustBePaused=Must be paused +InvalidMods=SCORE INVALIDATED BY: +CustomizeGameplayInstruction=Space to scroll movement types +Spacing=Spacing +Height=Height +Width=Width +Zoom=Zoom +Rotation=Rotation +BPMText=BPM Text +Combo=Combo +Cover=Lane Cover +DisplayMean=Mean Display +DisplayPercent=Percent Display +DisplayEWMA=EWMA Display +DisplayStdDev=StdDev Display +ErrorBar=Error Bar +FullProgressBar=Full Progress Bar +JudgeCounter=Judge Counter +Judgment=Judgment +LifeP1=Lifebar +MusicRate=Music Rate Display +NoteField=NoteField +NPSDisplay=NPS Display +NPSGraph=NPS Graph +PlayerInfo=Player Info +Screen=Screen +TargetTracker=Target Tracker +ErrorBarLate=Late +ErrorBarEarly=Early +MeanDisplayFormatStr=%5.2fms +EWMADisplayFormatStr=%5.2fms +StdDevDisplayFormatStr=%5.2fms +NPSDisplayPeak=Peak +NPSDisplayNPS=NPS +JudgeDifficulty=Judge +ScoringType=Scoring +CreatedBy=By + +[ScreenHelpMenu] +Title=Help +Exit=Exit +Instruction=Select an item on the left to get info.\nScroll through the list for more categories. +CategoryCommon Pattern Terminology=Common Pattern Terminology +CategoryHotkeys=Hotkeys +CategoryHow-To=How-To +CategoryInformation=Information +CategoryTroubleshooting=Troubleshooting +RollAscending=Roll (1234) +RollAscendingShortDescription=Vaguely a jumptrill +RollAscendingDescription=Roll is the common name given to this type of pattern which requires you to press all columns in succession before repeating any columns again. It comes in several forms.\n\nThe specific roll depicted here may be referred to as an ascending roll. If it went in the opposite direction (4321) it would be descending.\n\nThe direction of the roll does not affect its capacity to be jumptrilled. Only the speed of the roll does. +RollInward=Roll (1243) +RollInwardShortDescription=Vaguely a jumptrill +RollInwardDescription=Roll is the common name given to this type of pattern which requires you to press all columns in succession before repeating any columns again. It comes in several forms.\n\nThe specific roll depicted here may be referred to as a split roll. If the pattern began with the opposite hand (4312) it would be functionally equivalent.\n\nRegardless, this roll variant can be effectively jumptrilled if its speed is sufficient. +RollSplit=Roll (4132) +RollSplitShortDescription=Vaguely a split jumptrill +RollSplitDescription=Roll is the common name given to this type of pattern which requires you to press all columns in succession before repeating any columns again. It comes in several forms.\n\nThe specific roll depicted here may be referred to as a split roll, split hand roll, or split trill. It may also begin in reverse order (3241, inside out) but still remains functionally equivalent.\n\nThis roll variant is more difficult to jumptrill than others. When hit quickly, it is physically similar to a split jumptrill. +Gluts=Gluts +GlutsShortDescription=Another word for 'in excess' +GlutsDescription=Gluts is a broad term which captures jumpgluts and handgluts. It's frequently debated what defines a glut or even if a handglut exists.\n\nThe most accepted definition of a glut is literal: jumpgluts are many continuous jumps (jumpjacks) which typically form minijacks as they change column pairs over the course of the glut run. Depicted in the image is a run of jumpjacks referred to as gluts because of the minijacks on column 1 and 4.\n\nGluts are a subset of chordjacks with more focus on jack speed than chords. +Chordjack=Chordjack +ChordjackShortDescription=Chords which form jacks +ChordjackDescription=Chordjack is the blanket term for patterns made up entirely of n-chords which form jacks.\n\nThe chords contained in the overall pattern do not have to be the same. Jumps, hands, or quads are valid. Depicted to the right is a very generic medium density chordjack pattern containing only jumps and hands. +DenseChordjack=Dense Chordjack +DenseChordjackShortDescription=Don't break your keyboard +DenseChordjackDescription=Dense chordjacks are a specialization of chordjacks which are biased toward hands and quads. At high enough density, this may be referred to as holedodge because when reading, there are more notes than empty spaces.\n\nDense chordjacks require a lot of stamina and tend to have embedded longjacks due to the pattern being almost entirely hands and quads. +Stream=Stream +StreamShortDescription=Continuous single taps +StreamDescription=Just like the name implies, a stream is a continuous stream of notes. More specifically, these continuous notes are mostly on separate columns, not forming jacks. There can be any kind of variation to the patterning as long as it doesn't deviate too much from the pure definition.\n\nMinijacks, chords, or other patterns that can be embedded may be found within a stream, but only serve to make it more difficult unless they dominate the overall pattern.\n\nTo the right is a stream which is slightly rolly. +Jumpstream=Jumpstream +JumpstreamShortDescription=Stream with jumps +JumpstreamDescription=Jumpstream expands the definition of a stream by requiring jumps at a certain frequency within the pattern. Other than that, it is still a stream.\n\nDepicted to the right is a simple jumpstream pattern with an anchor on column 1. A more observant player may also recognize that this pattern in isolation can be jumptrilled. +Handstream=Handstream +HandstreamShortDescription=Stream with hands +HandstreamDescription=Handstream expands the definition of a stream by requiring hands at a certain frequency within the pattern. It is also not uncommon to find jumps embedded within a handstream. This may be referred to as dense handstream, although the most dense handstream is purely hands and single taps.\n\nAnchors are more common in a handstream since the charter only has 4 ways to fit a hand into 4 columns. In the depiction to the right, there is an anchor on column 4 and, depending who you ask, also column 3. +Quadstream=Quadstream +QuadstreamShortDescription=Stream with quads +QuadstreamDescription=Quadstream takes the definition of stream so far that it begins to look like chordjacks.\n\nIt forms a minijack with a quad using a single tap (usually) and still flows like a stream as opposed to pure chordjacks.\n\nIncreasing the density of quads will lose this characteristic due to the limited column space. +Trill=Trill +TrillShortDescription=Like musical theory +TrillDescription=A trill is a sequence of two continuously alternating notes. In the context of this game, they can be either on one hand or split between both hands.\n\nWhen a trill is one handed, it is called a one hand trill. Otherwise, it is a two hand trill. Trills are not restricted to two adjacent columns, and can be on columns 1 and 3 for example.\n\nDepicted to the right is a simple two hand trill. +Jumptrill=Jumptrill +JumptrillShortDescription=Can be played blind +JumptrillDescription=Jumptrill is a very simple expansion of a two hand trill. Jump on one hand and then jump on the other. Most often this pattern makes up the highest NPS section of a chart unless it is dense chordjacks.\n\nOne special thing about the ordinary jumptrill is that many other patterns can be broken down into a jumptrill, which allows cheese-oriented gameplay. We don't recommend doing this too frequently for the sake of your scores and habit forming. +SplitJumptrill=Split Jumptrill [13][24] +SplitJumptrillShortDescription=Jumptrill but dangerous +SplitJumptrillDescription=Split jumptrill is a shuffled jumptrill. It forms two one hand trills instead of one pure jumptrill.\n\nSplit jumptrills are very annoying due to many players' inability to hit them fluently. This specific variant of split jumptrills can be more difficult than the other variant of split jumptrills because a player tends to be more inclined to jumptrill or roll when simultaneously doing a same-direction rolling motion with both hands. Luckily they can be jumptrilled if hit just right.\n\nTo the right is a long split jumptrill. +SplitJumptrillTrainTrack=Split Jumptrill [14][23] +SplitJumptrillTrainTrackShortDescription=Jumptrill but dangerous +SplitJumptrillTrainTrackDescription=Split jumptrill is a shuffled jumptrill. It forms two one hand trills instead of one pure jumptrill.\n\nSplit jumptrills are very annoying due to many players' inability to hit them fluently. Compared to the other variant of split jumptrills, this one is usually easier because it can feel more natural. Anyways, they can be jumptrilled if hit just right.\n\nTo the right is a long split jumptrill. +Minijacks=Minijacks +MinijacksShortDescription=Instant combo breaker +MinijacksDescription=Minijacks are pairs of jacks. They can be continuous like the image to the right or embedded in some other pattern like a stream.\nMinijacks can be difficult to hit accurately as they get closer together because of the nature of the hit window. Imagine hitting one note within 180ms. Now hit two notes in that same window. If the minijack is fast enough or the player is slow enough, it's guaranteed points lost.\nMinijacks can be embedded within broader jack oriented patterns as a jack burst. Most commonly they are in isolation or in stream transitions that jack instead of trill. +Longjack=Longjack +LongjackShortDescription=Continuous taps +LongjackDescription=A jack, or jackhammer, is a set of continuous taps in the same column. A longjack is the same thing, but a little longer than usual.\n\nThe length of a jack that is considered a longjack is debated, but generally it is around 5-6 notes. The longjack can continue into infinity.\n\nLongjacks are the base pattern which make up continuous jumpjacks, handjacks, or quadjacks. This base pattern also makes up much of the structure for files oriented towards the vibro playstyle. +Anchor=Anchor +AnchorShortDescription=Basically embedded longjacks +AnchorDescription=An anchor is a common continuous set of columns being utilized relative to the other columns contained in a pattern. Most commonly, anchors are only one column at a time.\n\nAn anchor may be on a snap alternating from the rest of the pattern or not, or a bit of both. Anchors that last a while break down to be longjacks, which will cause an overall pattern to be more stamina draining.\n\nThe image to the right depicts an anchor on column 4. +Minedodge=Minedodge +MinedodgeShortDescription=Spicy notes +MinedodgeDescription=Minedodge is the term for a type of chart or general pattern which contains notes that are intentionally placed near mines to increase difficulty.\n\nMinedodge does not actually change the MSD of a chart, because the calculator measures physical difficulty of the taps.\n\nThe difficulty of minedodge comes from the necessity of more precisely timing the press and release of notes and increased difficulty to read the notes depending on the noteskin used. +Hold=Hold +HoldShortDescription=Don't let go +HoldDescription=Holds are a note type which require the player to hold the button for the entire duration of the note. They may also be referred to as freezes or long notes.\n\nPatterns made up of more holds are sometimes referred to as a holdstream or, at the extreme end of the spectrum, full inverse (all empty space is a hold).\n\nIn this game, a hold can be released for a short period of time dependent on the judge difficulty. On judge 4, the time is 250ms. Holds can then be regrabbed. Holds do not have release timing, but release timing can be emulated with a lift or mine. +Rolld=Roll / Rolld +RolldShortDescription=Keep tapping +RolldDescription=Roll note types, not to be confused with the roll pattern, are a hold type which require the player to continuously tap the button for the duration of the note. They may also be referred to as a rolld.\n\nRolls cannot be held and must be continuously tapped. The speed of the tap has a threshold the player receives no judgment for, but it gets smaller at higher judge difficulties. On judge 4, the player has up to 500ms between taps. +Burst=Burst +BurstShortDescription=Explosive speed +BurstDescription=A burst is a pattern specialization which means exactly what it says. Relative to its pattern context, a burst is much quicker.\n\nBursts can come in any form which matches that definition, not only the scenario depicted to the right. Jacks and jumpstream can also burst. The point is that it is a quicker collection of notes, almost like a compressed pattern.\n\nOften, a burst is patterned in such a way that it isn't difficult to full combo. But that isn't always the case! +Polyrhythm=Polyrhythm +PolyrhythmShortDescription=Brain melting patterns +PolyrhythmDescription=Polyrhythms are a pattern specialization which indicates that multiple rhythms are being charted simultaneously, leading to alternating snaps being utilized. Sometimes the result of this is a very awkward, technically difficult to execute pattern.\n\nTo the right is a depiction of a simpler polyrhythm of 16ths and 12ths. +Graces=Graces / Flams +GracesShortDescription=A little extra flare +GracesDescription=Grace notes are slightly offset notes, exceptionally rarely forming minijacks, which represent a kind of grace or extra flare to an initial note.\n\nIn musical theory, these are defined as not so necessary, but typically when these are charted it means that a grace note was present in the music.\n\nFlams are made up of graces. Within this game, both usually mean the same. Graces usually break down to be a single chord, and can rarely contain chords themselves. +Runningman=Runningman +RunningmanShortDescription=Anchored stream +RunningmanDescription=Classically, runningman is a term referring to a stream that is anchored. We expand on that definition by allowing chords to be mixed in very lightly. An anchored jumpstream can technically contain a runningman, but is more likely to just be referred to as anchored jumpstream.\n\nIt is required that the anchor in a runningman be offset from the rest of the pattern so that it doesn't form chords with the rest of the pattern.\n\nTo the right is a runningman anchored on column 1. The off-taps may be on any column, but it is important that not too many taps be on the same hand as the anchor. +GlobalHotkeys=Global Hotkeys +GlobalHotkeysShortDescription=Hotkeys available anywhere +GlobalHotkeysDescription=F2 -- Reload Textures & Metrics\nF2 + Shift -- Reload Metrics\nF2 + Ctrl -- Reload Scripts\nF2 + Shift + Ctrl -- Reload Overlay Screens\nF3 -- Debug Menu (many shortcut options within)\nF9 -- Toggle author-defined metadata transliteration\nAlt + Enter -- Fullscreen Toggle\nTab -- Speed up animations x4\n~ -- Slow down animations x4\nPause|Break -- Toggle menu sounds\nPrintScreen -- Screenshot +SelectMusicHotkeys=SelectMusic Hotkeys +SelectMusicHotkeysShortDescription=Hotkeys only in song selection +SelectMusicHotkeysDescription=F1 -- Song Search\nCtrl + Q -- Load new song folders\nShift + Ctrl + R -- Reload current song folder\nShift + Ctrl + P -- Reload current pack folder\nCtrl + F -- Favorite chart toggle\nCtrl + M -- Permanent mirror chart toggle\nCtrl + G -- Create goal on current chart\nCtrl + O -- Toggle practice mode\nCtrl + S -- Save profile\nCtrl + P -- Create playlist\nCtrl + A -- Add current chart to selected playlist\nCtrl + Number -- If main box active, access the top right buttons. If not, access main box tabs.\nNumber -- Switch tabs in main box/settings\nEscape/Back -- In side box context, exit to main box\nCtrl + L -- Login/Logout\nSpace -- General Tab/Settings Chart Preview toggle\nRight Click -- Pause music toggle if functionality not overridden +GameplayHotkeys=Gameplay Hotkeys +GameplayHotkeysShortDescription=Hotkeys only in regular gameplay +GameplayHotkeysDescription=Hold Enter -- Force Fail\nF4 -- Undo sync changes before saving them\nF6 -- Toggle through Autosync Song, Autosync Machine\nF7 -- Toggle claps\nLeftShift + F7 -- Toggle metronome\nF8 -- Toggle autoplay\nF11 -- Move song offset earlier\nAlt + F11 -- Move song offset earlier (small increment)\nF12 -- Move song offset later\nAlt + F12 -- Move song offset later (small increment)\nShift + F11 -- Move global offset earlier\nAlt + Shift + F11 -- Move global offset earlier (small increment)\nShift + F12 -- Move global offset later\nAlt + Shift + F12 -- Move global offset later (small increment) +CustomizeGameplayHotkeys=Customize Gameplay Hotkeys +CustomizeGameplayHotkeysShortDescription=Hotkeys only in gameplay customization +CustomizeGameplayHotkeysDescription=Enter -- Select element or Deselect element\nDelete/Backspace/RestartGameplay -- Undo only the most recent change\nCtrl + Undo -- Reset selected element to default\nRight Click -- Deselect element\nDirectional -- Menu movement or selected element movement\nShift + Directional -- Smaller increment movement\nSpace -- Scroll through movement types of selected element +PracticeHotkeys=Practice Hotkeys +PracticeHotkeysShortDescription=Hotkeys only in practice mode +PracticeHotkeysDescription=Backspace -- Jump to loop region start or bookmarked position\nEffectUp -- Increase rate 0.05x\nEffectDown -- Decrease rate 0.05x\nInsertCoin -- Set bookmark position or loop region boundaries\nInsertCoin twice while paused -- Reset loop region to a bookmark position\nMousewheel Scrolling -- If paused, move song position in fine increments\nRight Click -- Toggle pause\nLeft Click Graph -- Jump to position\nRight Click Graph -- Set bookmark or loop region boundaries +ReplayHotkeys=Replay Hotkeys +ReplayHotkeysShortDescription=Hotkeys only in replays +ReplayHotkeysDescription=InsertCoin -- Toggle pause\n\nMust be paused before using any of the following:\nAlt + EffectUp -- Set bookmark position\nAlt + EffectDown -- Go to bookmark position\nShift + EffectUp -- Increase rate 0.05x\nShift + EffectDown -- Decrease rate 0.05x\nEffectUp -- Move song position 5 seconds\nCtrl + EffectUp -- Move song position 0.1 seconds\nEffectDown -- Move song position -5 seconds\nCtrl + EffectDown -- Move song position -0.01 seconds +EvaluationHotkeys=Evaluation Hotkeys +EvaluationHotkeysShortDescription=Hotkeys only in the evaluation screen +EvaluationHotkeysDescription=Ctrl + L -- Login/Logout\nUp/Down -- Scroll through column highlight settings\nEffectUp -- Increase display judge\nEffectDown -- Decrease display judge\nSelect -- Screenshot\nLeft + Right -- Screenshot +MultiplayerHotkeys=Multiplayer Hotkeys +MultiplayerHotkeysShortDescription=Hotkeys only in multiplayer +MultiplayerHotkeysDescription=Multiplayer isn't finished! +HowToCreateCharts=Create Charts +HowToCreateChartsShortDescription=Notes to noises +HowToCreateChartsDescription=You need an editor. Etterna doesn't currently come with an editor. The popular choices are ArrowVortex and DDReam. Others also choose to use the osu editor or older SM3/SM5 editors.\n\nWhat matters is you have a way to place notes and get them to a valid format like .sm.\n\nA chart only requires audio and the metadata file (.sm for example) to load. Be careful not to attempt to load the chart before both of these are present in your Etterna Songs folder.\n\nMore extensive tutorials on chart creation exist online, and most people are willing to help if you ask around. +HowToManualSongInstall=Manual Song Install +HowToManualSongInstallShortDescription=When downloading in client isn't your thing +HowToManualSongInstallDescription=Here's the scenario: you've created or downloaded a single song or a pack of songs. Now you need to make them load in the game.\n\nIdeally, the folders are structured in this pattern - /Packname/Songname/stuff.sm\n\nIf this applies to a pack you just downloaded, all you must do is extract the pack folder and place it in your Songs folder. The structure is then /Songs/Packname/Songname/stuff.sm.\n\nIf you have a single song, you should create a new pack folder for it in the Songs folder. It can have any name. After all of this is completed, either reopen the game or press Ctrl + Q in SelectMusic.\n\nIf for some reason you want to keep your install separate from your songs, open Preferences.ini and add a direct path to a new Songs folder in the AdditionalSongFolders field. +HowToDownloadPacks=Download Packs +HowToDownloadPacksShortDescription=How to press a button +HowToDownloadPacksDescription=Ingame, downloading packs is very simple. If you have no packs installed, you may be led first to the core bundle select screen which shows a few sets of packs of varying difficulty to get you started.\n\nIf you skipped that, don't want the bundles, or already have something installed, you can use the downloader screen in SelectMusic. In the top right, in the Ctrl + 3 menu, you should find every pack you could download from ingame. If this list is blank, you may not have an internet connection.\n\nThere are other sources of packs if these downloads ever fail which you must ask around for.\n\nDownloaded packs will extract and install automatically when finished. If it appears that they finish but nothing happens, the download may have failed instead. +HowToSongSearch=Song Search +HowToSongSearchShortDescription=Finding the song +HowToSongSearchDescription=You may have been expecting to be able to search for a song that you don't have installed. Let's get that out of the way first - it isn't currently possible from within the client.\n\nYou can search for songs that are installed using the F1 menu (the leftmost button in the top right of SelectMusic). The interface should be simple to use. Just fill out the fields you care for and hit enter, and the results come to you.\n\nOtherwise, places that host packs may offer search capabilities. +HowToSongFilter=Song Filter +HowToSongFilterShortDescription=Filtering the songs +HowToSongFilterDescription=The song filter is integrated with song search. It can be found in the F1 menu (the leftmost button in the top right of SelectMusic).\n\nThere is not currently any keyboard compatibility with this menu, but the sliders should be sufficient to let you set up a filter with your mouse. A slider placed at an extreme end is considered effectively 0 or infinite, a disabled bound.\n\nFilters stick if you happen to enter a song and come back, unlike the song search. +HowToSortmode=Sortmodes +HowToSortmodeShortDescription=Sorting the songs +HowToSortmodeDescription=The song wheel can be resorted in different predefined ways.\n\nTry pressing up-down-up-down in the main area, and it changes your wheel into a menu to select a sortmode. Some people will find some sortmodes more useful than others.\n\nMost of the time, Group sort is used because it is the natural order everyone expects. Some sorts are for more informational purposes.\n\nIf you would like to modify the behavior of these sortmodes, check out the implementation in Scripts/WheelDataManager. +HowToCustomizeGameplay=Customize Gameplay +HowToCustomizeGameplayShortDescription=Power at your fingertips +HowToCustomizeGameplayDescription=Customize Gameplay is the gameplay screen which allows you to modify every element on the screen in almost any way to make it fit to your standard.\n\nOn the right side is the navigation and information panel which can be dragged around for visibility. The arrow keys can be used if the mouse is not preferred.\n\nEnter to select a highlighted element, or click an element to select it. Use space to change which movement type you are modifying (coordinates vs sizing). Some elements do not offer more than one type. The mouse can be used to drag around any element.\n\nHold shift to move with smaller increments. Use RestartGameplay to undo or hold Ctrl with it to reset to default.\n\nAll changes are saved to disk as soon as you exit the screen. +HowToUpdate=Update Etterna +HowToUpdateShortDescription=Backup your user data +HowToUpdateDescription=Updating Etterna is typically a painless process on all platforms. In all cases, we would recommend you take a backup of any content you directly added to the game - Noteskins, Save, Assets. Songs do not need to be backed up.\n\nOn Windows, the installer may ask for you to uninstall the old version, and the uninstaller can fail. It's safe to ignore that. As long as you are not directly overlaying the latest version on top of the old one, your new install will run fine.\n\nOn Mac, updating is simply reinstalling the game again, but with less configuration.\n\nOn Linux, updating can be moving to the latest binary or a git pull and rebuild.\n\nThe most important folder you never want to lose is the entire Save folder. Nearly every file in this folder is related to user scores or settings in some way. +HowToSetSync=Set Sync/Offset +HowToSetSyncShortDescription=Notes follow music, you know +HowToSetSyncDescription=Every player will experience an issue at some point which manifests in their tap offsets being generally late or generally early. This translates to a late or early mean. In any scenario, a negative offset or mean indicates 'early.'\n\nIf you suffer from an unplayable offset or a consistently bad mean (> 5-10ms +/-) here's a few things to try.\nEtterna offers a visual offset (also called the judge offset), a global (machine) offset, and a song offset. The song offset is set by each chart author, and if it ever ends up wrong, that tends to be their fault and not yours.\nMoving the visual offset moves the visual position where a perfect hit is relative to your receptors. To change it, find it in the F3 menu or in the SelectMusic settings.\nGlobal offset applies to all songs in addition to the song offset. It changes the position of the audio relative to the notes. Ideally, it is 0ms, but can be nonzero if you have some audio/monitor/input related discrepancies.\nGlobal and song offsets can be set automatically by going into a song and pressing F6, then playing to the best of your ability. Try not to let autosync run more than 2 iterations.\nYou may also try moving them manually with F11/F12. +HowToChangeTheme=Change Theme +HowToChangeThemeShortDescription=It's not called a skin +HowToChangeThemeDescription=The general look of the game is called a Theme. Most of it is written in Lua.\n\nTo install a theme, you just extract its folder into the Themes folder of your install. You shouldn't ever have to backup this folder.\n\nTo change your theme, you can find the option in SelectMusic settings, or in Display Options. It won't look the same as this theme though. +HowToChangeLanguage=Change Language +HowToChangeLanguageShortDescription=We need translators +HowToChangeLanguageDescription=Etterna comes with a partial translation into a few popular languages, but overall none of them are nearly as sufficient as we would like them to be.\n\nTranslation support is always on our mind, but not a very high priority.\n\nTo change language and see what things look like, find it in Display Options or in SelectMusic settings. +HowToToggleMenuSound=Toggle Menu Sounds +HowToToggleMenuSoundShortDescription=Beep +HowToToggleMenuSoundDescription=Sometimes menu sounds are annoying.\n\nTo turn them off, press Pause on your keyboard, or find the option in the F3 menu F5 page or in SelectMusic settings. +HowToTogglePitchRates=Toggle Pitch Rates +HowToTogglePitchRatesShortDescription=Nightcore Remix +HowToTogglePitchRatesDescription=Some players enjoy high pitch noises more than others, and some players are better when the song is just faster but not high pitched.\n\nTo toggle pitch usage on rates, find it in the F3 menu F8 page, Advanced Options, or SelectMusic settings. +HowToSwapWheelSide=Swap Wheel Side +HowToSwapWheelSideShortDescription=Change is bad +HowToSwapWheelSideDescription=Understandably, some people are bound to not like the fact that the wheel defaults to the left side in Rebirth.\n\nTo swap sides, find the wheel position option in SelectMusic settings > Graphics > Theme Options. +HowToLogin=Login +HowToLoginShortDescription=Using Online Functionality +HowToLoginDescription=Login is required if you ever want to upload scores or view leaderboards.\n\nTo begin the login process, you click the broken link in the top left or press Ctrl + L while in SelectMusic. Doing the same again will log you out.\n\nLogging in this way is not required to play multiplayer. Instead, you are separately asked to log in to that, if it is required. +HowToUpload=Upload Scores +HowToUploadShortDescription=Flex your 89% on Game Time +HowToUploadDescription=You must first be logged in to upload any score.\n\nEvery time you log in (and if you automatically log in at the start of a session) Etterna will try to upload any scores you have set that have not yet been uploaded. Scores will also attempt to upload immediately after setting a score, even before your profile saves.\n\nOnly scores on ranked charts will be uploaded. You can see if a chart is ranked by checking its leaderboards in the Scores tab.\n\nTo try force uploading, find the upload buttons either in the Profile tab or the Scores tab.\n\nEtterna uploads things in the background, so there is no clear progress indicator. Just trust.\n\nScores worth 0.00 or that are otherwise invalid will not upload. +HowToFavoriteSongs=Favorite Songs +HowToFavoriteSongsShortDescription=Ear worms +HowToFavoriteSongsDescription=Your song library might become huge and Favoriting is a way to keep track of the files you really like. Just press Ctrl + F on a chart and it becomes a Favorite. Do the same again to remove it.\n\nFavorites can be viewed as a playlist or in the Favorites sortmode if you press Up-Down-Up-Down. +HowToPermamirror=Permanently Mirror Charts +HowToPermamirrorShortDescription=Hand bias bad +HowToPermamirrorDescription=Some charts out there are very biased toward one hand, and some players have particularly bad hands. Because Etterna calculates based on physical difficulty and mirroring a chart is still equivalent because only the hands are swapped, mirroring is a core feature of the game and is ranked.\n\nSome charts might need to always be mirrored for some players, but the players might not want to leave mirror on for everything. Permamirror is the solution.\n\nTo permanently toggle mirror on a specific chart, hover it and press Ctrl + M. Every time you open it, mirror will be on. +AboutKeymodes=About keymodes +AboutKeymodesShortDescription=Styles, StyleTypes, StepsTypes, Games ... +AboutKeymodesDescription=At its root, this game is a simulator for several other real games. This is why keymodes are separated by Game, and then further by Style.\n\nDance - The core game. 4k. Dance-double can be found here, and is 8k. Also contains a 3k type.\nSolo - Separated from the core game, 6k.\nBeat - The BMS game. 5k+1, 7k+1, and doubles for both.\nKb7 - A gamemode that didn't take off, 7k.\nPump - 5k, 6k, and 10k in single, halfdouble, and doubles.\nPopn - Yes, popn. 5k and 9k.\n\nWithin a game, each style is visible in the difficulty displays. You can switch game in SelectMusic settings or the Select Game screen in Options. +AboutCleartypes=About cleartypes +AboutCleartypesShortDescription=The MF Miss Flag +AboutCleartypesDescription=Scores are assigned flags called cleartypes. They are additional indications of the quality of your score at a glance. You are only assigned 1 cleartype for a score.\n\nMFC - Marvelous Full Combo - All Marvelous\nWF - White Flag - All Marvelous but 1 Perfect\nSDP - Single Digit Perfects - Marvelous and Perfect only, but no more than 9 Perfects\nPFC - Perfect Full Combo - All Marvelous and Perfect\nBF - Black Flag - All Marvelous and Perfect, but 1 Great\nSDG - Single Digit Greats - A Full Combo, but no more than 9 Greats\nFC - Full Combo - No combo breakers, such as Good, Bad, Miss, or Holds Dropped\nMF - Miss Flag - Almost a Full Combo: 1 combo breaker\nSDCB - Single Digit Combo Breakers - Almost a Full Combo: up to 9 combo breakers\nClear - You passed\nFailed - You didn't pass +LegacyKeyConfig=Old Key Config +LegacyKeyConfigShortDescription=You shouldn't need this +LegacyKeyConfigDescription=Old key config can still be accessed through the main menu options. The left half of the screen is where the relevant controls are - it's the Player 1 side. The right half is for Player 2, but now those controls are dead. The default columns cannot be modified directly.\n\nTo unbind a default control, rebind that key to a different button on the right side that is infrequently used.\n\nIf you only use the key rebinding screen in Rebirth, you never have to use this screen.\n\nBe aware - just because this screen allows you to bind the same button to multiple keys to play with does not mean that setting scores using that kind of setup is allowed. The feature is meant more for people with a particular playstyle or restriction. +ReplayInfo=Replays +ReplayInfoShortDescription=Stuck in the past +ReplayInfoDescription=Local and online replays can be viewed for scores where valid replay data is present.\n\nLocal replays can be viewed if the replay is present in Replays or ReplaysV2. You have to find the score in the scores tab, and then click the button to view the replay.\n\nOnline replays can be viewed straight from the chart leaderboards.\n\nWhile in a replay, you can pause and change rates or seek around. The large progress bar can be used as a seeking bar.\n\nEvaluation will show a reconstruction of the actual score's evaluation screen. +SelectMusicTips=SelectMusic Tips +SelectMusicTipsShortDescription=Speedy menu navigation +SelectMusicTipsDescription=SelectMusic contains a long list of hotkeys that make navigation quick. Memorizing many of them will be very helpful. Find the page on SelectMusic hotkeys to learn more.\n\nCertain parts of the UI have extra mouse functionality. Clicking the header of the wheel will randomly pick a group or a song in the current group. Clicking certain text in the Overall page of the profile tab toggles the displayed information. Clicking the banner of a song opens chart preview.\n\nThe music wheel scroll bar can be clicked or dragged to quickly navigate through songs. Right clicking scores in the profile tab invalidates them.\n\nEscape is a very useful button to exit the side menus that come up when using the buttons at the top of the screen. +ProfileTab=Profile Tab Usage +ProfileTabShortDescription=Your Profile and You +ProfileTabDescription=The Profile tab contains most relevant information about your game usage and scores. The Overall section gives a glance at online and offline ratings as well as general stats. Here, you can upload all scores (that haven't been uploaded) or revalidate all scores locally. You can also click the Player Ratings text to switch it to Player Stats for more information.\n\nIn the View Recent Scores button, or any of the other tabs, you can view several hundred of your scores organized by whichever condition the tab specializes in. Stream for example sorts everything by stream. Recent scores sorts them by date. +GoalsTab=Goals Tab Usage +GoalsTabShortDescription=Strive to be better eventually +GoalsTabDescription=The Goals tab contains a listing of goals you created on charts which you intend to eventually reach. That's the nature of a goal. By default, all goals start at priority 1, rate 1x, and 93%. These attributes can be clicked to increase or decrease them.\n\nTo create a goal, there's a button for it in the tab or you can use Ctrl + G.\n\nThe top buttons of the tab are for sorting the list of goals. The rightmost button filters the list by complete status.\n\nA vacuous goal simply means that the goal is pointless because you have already set a score that beats it. Remove it or make a higher goal.\n\nGoals save to your XML. +PlaylistsTab=Playlists Tab Usage +PlaylistsTabShortDescription='Courses' +PlaylistsTabDescription=The Playlists tab lets you create multiple lists of charts to play or refer back to. These don't actually have to be used to play in succession like a course, but can serve to be lists of files.\n\nTo create a playlist, Ctrl + P can be used or you can use the New Playlist button. Then click a playlist name to enter it.\n\nTo add charts to the selected playlist, use Ctrl + A or click the Add Current Chart button. The rate a chart gets played on in a course playback can be changed if you click the rate in the detail list.\n\nA playlist cannot be reordered.\n\nPlaylists save to your XML. +TagsTab=Tags Tab Usage +TagsTabShortDescription=Describe your charts +TagsTabDescription=The Tags tab lets you put description tags on charts so you can either describe them in your own way or filter based on the tags.\n\nAny number of tags can be assigned to a chart. Assigned tags (up to a certain amount) will show up in the General tab, and also as a different color in the Tags tab.\n\nThe Require Tag button sets a filter on all songs that requires the tag is assigned. The Hide Tag button does the opposite - any song with that tag is not visible. You must click Apply to set these filters.\n\nTo assign tags to a chart, just click the Assign button then click some tags.\n\nDeleting tags is a 2 step process started by clicking Delete.\n\nThe Reset button resets all filters. It does not delete any tags.\n\nTags are saved in a tags.lua file which can be shared with other people. +GettingSupport=Getting Support +GettingSupportShortDescription=Not for spoonfeeding +GettingSupportDescription=Sometimes getting Etterna set up or getting things fixed is not a simple process. Well ... it is to a lot of us, but not everyone.\n\nSince many people know the solution to a lot of common issues, if you ever need help, you are free to ask around in the Etterna communities for help. Github issues (can be found on the Title Screen) is a place to report bugs, not ask for help.\n\nDiscord servers that have answers to your questions can be found on the front page of the Github repo, or any website associated with this game. +Softlocked=Softlocked +SoftlockedShortDescription=Locked in +SoftlockedDescription=In some rare conditions, not just in Rebirth, the game can lock but not hard crash or freeze. You can tell that this is what is happening if some buttons might work, but you can't advance or move or go back.\n\nThe instant solution to a softlock is Ctrl + Operator. By default, Operator is set to Scroll Lock. It can be rebound in the old key config. Pressing this combo will send you to the options menu.\n\nF3 + F8 + 9 will also put you in old key config.\n\nIf you ever end up in a softlock condition, it is helpful to be able to consistently reproduce and then describe how you did it in detail in a Github issue so that we can patch it. +InputBroke=All Input Broke +InputBrokeShortDescription=The menu just laughs at you +InputBrokeDescription=Rebirth has some input quirks which can one way or another cause your menu navigation to completely stop working or work incorrectly.\n\nTo solve this, you can first try to escape back to the main menu. If not possible or you are already there, try reloading scripts and then overlays - Ctrl + F2 and then Ctrl + Shift F2. Then reload the screen by pressing F3 + F6 + 2.\n\nIf you ever end up in this scenario, it is very helpful to report it. +GeneralTips=General Tips +GeneralTipsShortDescription=Blanket fixes +GeneralTipsDescription=Lots of random things happen in this game. Here's some things to try before crying about it.\n\nRebirth locks, input issues, and error spam can be temporarily solved usually by reloading scripts, overlays, and the current screen. Ctrl + F2 > Ctrl + Shift F2 > F3 + F6 + 2. When developing on this theme especially, you will want to know this combo.\n\nCtrl + Operator or F3 + F8 + 9 will get you out of any softlock.\n\nIf input or the graphics don't work for some reason, rebooting is usually a fix.\n\nConstant crashing on startup is usually caused by putting random garbage in pack folders or 0 BPM related issues. +SongDoesntLoad=Song Doesn't Load +SongDoesntLoadShortDescription=Mysterious +SongDoesntLoadDescription=Sometimes when creating charts, authors find that the chart they are working on never appears. There's a reason for this (it's mostly a bug)\n\nIf you put music into a song folder without a .sm and restart or Ctrl + Q at any point, the folder is now forever ignored as not a song directory. The same applies if you put a .sm in that folder but it contains no charts.\n\nTo be safe, you should put audio with the .sm and a valid chart in before restarting or using Ctrl + Q. This will load the new song fine.\n\nIf this situation ever comes up, to solve it you must either delete the Cache folder or rename the song folder. +SongDoesntUpdate=Song Doesn't Update +SongDoesntUpdateShortDescription=When you don't know features +SongDoesntUpdateDescription=When editing charts, authors may run into an issue where the notedata they set is updated when they go to playtest, but the song ends early or late. Or none of the metadata updates to what they saved it as.\n\nThe reason for this is that the game has a cache which it typically blindly trusts. It loads new notedata from disk when going into gameplay, but will not modify chart properties based on that notedata.\n\nTo fix this, hover the song and press Ctrl + Shift + R. That will update the song from disk. +ScoresDontSave=Scores Don't Save +ScoresDontSaveShortDescription=Rare bugs or game misuse +ScoresDontSaveDescription=There are a couple of scenarios you may find yourself in if scores stop saving.\n\nThe usual one is that you've accidentally turned off Save Scores. This is an option that is found somewhere in the menus. It normally shouldn't be turned off.\n\nAnother is a rare bug called 0x where in the evaluation somehow your music rate is set to 0x, and now the likelihood that the rest of the session doesn't save is very high. To fix, just restart.\n\nThe last is a faulty install. You installed in a location where you don't have write permissions, such as Program Files. Or you ran out of disk space. +ScoresWorth0=Scores Worth 0.00 +ScoresWorth0ShortDescription=Invalid scores +ScoresWorth0Description=Scores become worth 0 instantly when the score is invalid upon creation.\n\nConditions for invalid scores:\nNegative BPMs or Warps\nInvalid modifiers (it is obvious which ones are being used)\nFile has less than 200 notes\nFailed\nChord Cohesion On\nAutoplay or Practice\nCertain lua mods active +RandomCrashes=Random Crashing +RandomCrashesShortDescription=That's life +RandomCrashesDescription=Sometimes the game crashes. Crashdumps should be generated in a folder within your Program folder.\n\nIf you opt in to crash uploading, you should just let us know in an issue or a report on Discord that you are having crash issues. Otherwise, still let us know but be ready to supply us with the associated .dmp file and logs.\n\nIf you keep crashing for no clear reason, it's always good to submit an issue or ask the community what is happening. + +[ScreenSelectMusic CurSongBox] +Length=LENGTH +BPM=BPM + +[ScreenSelectMusic General] +AverageNPS=Average NPS +NegativeBPMs=NegBPMs! + +[ScreenSelectMusic Goals] +DeleteGoal=Delete Goal +AlreadyBeat=Already Beat +VacuousGoal=Vacuous +AchievedGoal=Achieved +SetGoal=Set +PrioritySortDisplay=Priority +RateSortDisplay=Rate +MSDSortDisplay=MSD +NameSortDisplay=Name +DateSortDisplay=Date +NewGoal=New Goal +FilterShowAll=Showing All +FilterComplete=Showing Complete +FilterIncomplete=Showing Incomplete + +[ScreenSelectMusic Playlists] +PlayAsCourse=Play As Course +DeletePlaylist=Delete Playlist\n(Triggers a Save!) +DeleteChart=Delete Chart\n(Triggers a Save!) +NumberOfCharts=Number of charts +AverageMSD=Average MSD +NewPlaylist=New Playlist +AddCurrentChart=Add Current Chart +Back=Back + +[ScreenSelectMusic Profile] +SongsLoaded=songs loaded +PacksLoaded=packs loaded +CountVisible=visible +JudgeDifficulty=Judge +Top3PlayedSkillsets=Top 3 Played Skillsets +UploadAllScores=Upload all scores to EO +ValidateAllScores=Validate all scores +Plays=plays +ArrowsSmashed=arrows smashed +Playtime=playtime +ScoreStats=Score Stats +PackLamps=Pack Lamps +ScoreUploadMayBeSlow=May be slow - Will run in background +OnlineServer=EO +PlayerRatings=Player Ratings +OnlineSlashOffline=Online/Offline +PlayerStats=Player Stats +ViewRecentScores=View Recent Scores +ShowingLocalScores=Showing Local +ShowingOnlineScores=Showing Online + +[ScreenSelectMusic Scores] +LastScore=Last Score +You=You +NoName= +ShowOffsetPlot=Show Offset Plot +ShowReplay=Show Replay +ShowingJudge4Plot=Showing J4 Plot +ScoreBy=Score by +HowToCloseOffsetPlot=Click this box or do anything to close +UploadScore=Upload Score +UploadScorePack=Upload Score\nShift: All in pack +ShowEvaluation=Show Evaluation +JudgeDifficulty=Judge +JudgeJustice=Justice +ComboBreakers=Combo Breaks +MaxCombo=Max Combo +DateAchieved=Date Achieved +ScoreModsUsed=Mods +NoLocalScoresRecorded=No local scores recorded +ChartUnranked=Chart is unranked +FetchingScores=Fetching scores... +NoOnlineScoresRecorded=No online scores recorded +ShowOnlineScores=Show Online +ShowLocalScores=Show Local +ShowTopScores=Top Scores +ShowAllScores=All Scores +HideInvalidScores=Hide Invalid +ShowInvalidScores=Show Invalid +CurrentRateOnly=Current Rate +AllRates=All Rates + +[ScreenSelectMusic Tabs] +General=General +Scores=Scores +Profile=Profile +Goals=Goals +Playlists=Playlists +Tags=Tags + +[ScreenSelectMusic Tags] +AssignTag=Assign +RequireTag=Require Tag +HideTag=Hide Tag +ModeALL=Mode: AND +ModeANY=Mode: OR +DeleteTag=Delete +TagDeleteInProgress=Deleting Tag +NewTag=New +NewTagQuestion=Enter New Tag Name +ApplyFilter=Apply +ResetFilter=Reset + +[ScreenSelectMusic Wheel] +NumberOfSongs=Songs +AverageMSDShort=Avg +AverageMSDLong=Average MSD +PackClearedUsingDownrates=Clear +SessionTime=Session Time +SessionPlays=Session Plays +AverageAccuracy=Average Accuracy + +[ScreenTextEntry] +Information=Information +Exit=Exit [ScreenTitleMenu] Start=Game Start @@ -86,6 +581,412 @@ CoreBundles=Bundle Downloader GitHub=Github HelpMenu=Help ReportABug=Report a bug +UpdateAvailable=Update Available +By=by +Plays=plays +ArrowsSmashed=arrows smashed +Playtime=playtime +PlayerRatings=Player Ratings +OnlineRating=Online +OfflineRating=Offline +MakeFirstProfileQuestion=No Profiles detected! A new one was made for you.\nPlease enter a new profile name. +MakeProfileError=Do not leave this space blank. Do not use ':' +SelectProfile=Select a Profile + +[SearchFilter] +Title=Search and Filters +OmniSearch=Any Search +TitleSearch=Title Search +SubtitleSearch=Subtitle Search +ArtistSearch=Artist Search +AuthorSearch=Author Search +OverallFilter=Overall +SteamFilter=Stream +JumpstreamFilter=Jumpstream +HandstreamFilter=Handstream +StaminaFilter=Stamina +JackSpeedFilter=JackSpeed +ChordjacksFilter=Chordjacks +TechnicalFilter=Technical +LengthFilter=Length +ClearPercentFilter=Clear % +UpperBoundRate=Max Rate +LowerBoundRate=Min Rate +AnyAllMode=Mode +Any=OR +All=AND +HighestSkillsetOnly=Highest Skillset Only +HardestChartOnly=Highest Difficulty Only +On=ON +Off=OFF +Results=Matches +Reset=Reset +Apply=Apply + +[Settings] +NothingBound=none +CurrentlyBinding=Currently Binding +Controller=Controller +KeyBindingInstructions=Select a button to rebind with mouse or keyboard.\nPress Escape or click to cancel binding. +StartBindingAll=Start Binding All +ShowGameplayBindings=View Gameplay Keybindings +ShowMenuBindings=View Menu Keybindings +NewColorConfigPresetQuestion=NEW COLOR CONFIG PRESET\nPlease enter a new preset name. +NewColorConfigPresetUnknownError=There was an issue creating the new color config preset. You may try again.\nTo exit, press Esc. +NewColorConfigPresetInputError=Do not leave this space blank. Do not use illegal characters.\nTo exit, press Esc. +CurrentPreset=Current Preset +CurrentElement=Current element +CurrentColor=Current color +Undo=Undo +UndoShortcut=Alt-Delete +ResetToDefault=Reset to Default +Reset=Reset +ResetShortcut=Ctrl-Delete +SaveInstruction=Save (or press Enter) +SaveChangesUnsaved=Save Changes (Not Saved!) +SaveChanges=Save Changes +NewColorConfigPreset=New Color Config Preset +NewColorConfigPresetInstruction=New Preset: Ctrl-N +BrowsingColorCategories=Browsing Color Categories +BrowsingColorConfigPresets=Browsing Color Config Presets +BrowsingElements=Browsing Elements in +CurrentlyEditing=(editing) +BackToPresets=Back to Presets +BackToCategories=Back to Categories +OptionsHeader=Options +ToggleChartPreview=Toggle Chart Preview +PageNamePlayer=Player +PageNameGameplay=Gameplay +PageNameGraphics=Graphics +PageNameSound=Sound +PageNameInput=Input +PageNameProfiles=Profiles +CategoryEssential Options=Essential Options +CategoryAppearance Options=Appearance Options +CategoryInvalidating Options=Invalidating Options +CategoryGameplay Elements 1=Gameplay Elements 1 +CategoryGameplay Elements 2=Gameplay Elements 2 +CategoryGlobal Options=Global Options +CategoryTheme Options=Theme Options +CategorySound Options=Sound Options +CategoryInput Options=Input Options +CategoryProfile Options=Profile Options + +# opposite side header translations +Color Config=Color Config +Preview=Preview +Customize Keybinds=Customize Keybinds +Noteskin=Noteskin + +# rebirth custom choice names +Hidden=Hidden +Sudden=Sudden +Stealth=Stealth +Blink=Blink +Dark=Hide Receptors +Blind=Hide Judgment & Combo +Split=Split +Alternate=Alternate +Cross=Cross +Centered=Centered +Drunk=Drunk +Confusion=Confusion +Tiny=Tiny +Flip=Flip +Invert=Invert +Tornado=Tornado +Tipsy=Tipsy +Bumpy=Bumpy +Beat=Beat +Twirl=Twirl +Roll=Roll +Boost=Boost +Brake=Brake +Wave=Wave +Expand=Expand +Boomerang=Boomerang +Backwards=Backwards +Left=Left +Right=Right +Shuffle=Shuffle +SoftShuffle=Soft Shuffle +SuperShuffle=Super Shuffle +HRanShuffle=H-Ran Shuffle +Echo=Echo +Stomp=Stomp +JackJS=Jack JS +AnchorJS=Anchor JS +IcyWorld=IcyWorld +Planted=Planted +Floored=Floored +Twister=Twister +HoldRolls=Holds To Rolls +NoHolds=No Holds +NoRolls=No Rolls +NoJumps=No Jumps +NoHands=No Hands +NoLifts=No Lifts +NoFakes=No Fakes +NoQuads=No Quads +NoStretch=No Stretch +Little=Little +Wide=Wide +Big=Big +Quick=Quick +BMRize=BMRize +Skippy=Skippy +16bit=16bit +32bit=32bit +XMod=XMod +CMod=CMod +MMod=MMod +Upscroll=Upscroll +Downscroll=Downscroll +On=On +Off=Off +Yes=Yes +No=No +Left=Left +Right=Right +Tips=Tips +Quotes=Quotes +Hold=Hold +Instant=Instant +Justice=Justice +Overhead=Overhead +Incoming=Incoming +Space=Space +Hallway=Hallway +Distant=Distant +ExtraMines=Extra Mines +Regular=Regular +EWMA=EWMA +PersonalBest=Personal Best +GoalPercent=Goal Percent +Windowed=Windowed +Fullscreen=Fullscreen +Borderless=Borderless +Automatic=Auto +ForceOn=Force On +ForceOff=Force Off +Online=Online +Local=Local + +# rebirth custom option names +CustomizeGameplay=Customize Playfield +CustomizeGameplayExplanation=Customize Gameplay elements. +ScrollType=Scroll Type +ScrollTypeExplanation=XMod - BPM multiplier based scrolling. CMod - Constant scrolling. MMod - BPM based with a max speed. +ScrollSpeed=Scroll Speed +ScrollSpeedExplanation=Change scroll speed value/modifier in increments of 1 or 50. +ScrollDirection=Scroll Direction +ScrollDirectionExplanation=Direction of note scrolling: up or down. +OptionNoteskin=Noteskin +OptionNoteskinExplanation=Skin of the notes. +ReceptorSize=Receptor Size +ReceptorSizeExplanation=Size of receptors and notes. 50% Receptor Size may be called 100% Mini. +JudgeDifficulty=Judge Difficulty +JudgeDifficultyExplanation=Timing Window Difficulty. Higher is harder. All scores are converted to Judge 4 later. +Mirror=Mirror +MirrorExplanation=Horizontally flip Notedata. +GlobalOffset=Global Offset +GlobalOffsetExplanation=Global Audio Offset in seconds. Negative numbers are early. +VisualDelay=Visual Delay +VisualDelayExplanation=Visual Note Delay in seconds. May be referred to as Judge Offset. Negative numbers are early. +GameMode=Game Mode +GameModeExplanation=Dance - 3k/4k/8k | Solo - 6k | Pump - 5k/6k/10k | Beat - 5k+1/7k+1/10k+2/14k+2 | Kb7 - 7k | Popn - 5k/9k +FailType=Fail Type +FailTypeExplanation=Toggle failure in Gameplay. Setting Fail Off invalidates scores if a fail would have actually occurred. +CustomizeKeybinds=Customize Keybinds +CustomizeKeybindsExplanation=Customize Keybinds. +CustomizeKeybindsButton=Customize Keybinds +PracticeMode=Enter Practice Mode +PracticeModeExplanation=Enter Practice Mode +PracticeModeButton=Enter Practice Mode +Appearance=Appearance +AppearanceExplanation=Hidden - Notes disappear before receptor. Sudden - Notes appear later than usual. Stealth - Invisible notes. Blink - Notes flash. +HiddenOffset=Hidden Offset +HiddenOffsetExplanation=Offset the Hidden position. Hidden hides notes just before they reach the receptors. +SuddenOffset=Sudden Offset +SuddenOffsetExplanation=Offset the Sudden position. Sudden hides notes until they pass a certain distance across the screen. +Perspective=Perspective +PerspectiveExplanation=Controls tilt/skew of the NoteField. +PerspectiveIntensity=Perspective Intensity +PerspectiveIntensityExplanation=Controls the intensity of the tilt/skew of the NoteField. +HidingModifiers=Hide Player UI +HidingModifierExplanation=Hide certain sets of elements from the Gameplay UI. +Hidenote=Hidenote Judgment +HidenoteExplanation=Notes must be hit with this judgment or better to disappear. +CenterPlayer1=Default Centered NoteField +CenterPlayer1Explanation=Horizontally center the NoteField in Gameplay (Legacy Shortcut). +NoteFieldFilter=NoteField BG Opacity +NoteFieldFilterExplanation=Set the opacity of the board behind the NoteField in Gameplay. +BGBrightness=Background Brightness +BGBrightnessExplanation=Set the brightness of the background in Gameplay. 0% will disable background loading. +ReplayModEmulation=Replay Mod Emulation +ReplayModEmulationExplanation=Toggle temporarily using compatible mods that replays used when watching them. +ExtraScrollMods=Extra Scroll Mods +ExtraScrollModsExplanation=Change scroll direction in more interesting ways. +FunEffects=Fun Effects +FunEffectsExplanation=Visual scroll mods that are not for practical use. +Acceleration=Acceleration +AccelerationExplanation=Scroll speed mods usually not for practical use. +Mines=Mines +MinesExplanation=Toggle Mines. Extra Mines will replace entire rows of notes with mines. +Turn=Turn +TurnExplanation=Modify Notedata by either shifting all notes or randomizing them. +PatternTransform=Pattern Transform +PatternTransformExplanation=Modify Notedata by inserting extra notes to create certain patterns. +HoldTransform=Hold Transform +HoldTransformExplanation=Modify holds in Notedata. +RemoveMods=Remove +RemoveModsExplanation=Remove certain notes, patterns, or types of notes. +InsertMods=Insert +InsertModsExplanation=Modify Notedata by inserting extra notes to provide a certain feeling. +BPMDisplay=BPM Display +BPMDisplayExplanation=Toggle the BPM display. +RateDisplay=Rate Display +RateDisplayExplanation=Toggle the music rate display. +PercentDisplay=Percent Display +PercentDisplayExplanation=Toggle the wife percent display. +MeanDisplay=Mean Display +MeanDisplayExplanation=Toggle the tap mean display. +EWMADisplay=EWMA Display +EWMADisplayExplanation=Toggle the exponential weighted moving average display. This is a moving average of all your hits. +StdDevDisplay=Standard Deviation Display +StdDevDisplayExplanation=Toggle the standard deviation display. This displays the current SD of your whole play. +ErrorBar=Error Bar +ErrorBarExplanation=Toggle the error bar. Regular displays your recent tap offsets. EWMA displays the exponential weighted moving average of recent taps. +ErrorBarCount=Error Bar Count +ErrorBarCountExplanation=Choose either how many taps are allowed to show for the Regular error bar, or how many taps are considered for the EWMA error bar. +FullProgressBar=Full Progress Bar +FullProgressBarExplanation=Toggle the large progress bar. +MiniProgressBar=Mini Progress Bar +MiniProgressBarExplanation=Toggle the small progress bar. +Leaderboard=Leaderboard +LeaderboardExplanation=Toggle the gameplay leaderboard. Online shows only yourself and the online scores. Local shows only your own scores on the current rate. +PlayerInfo=Player Info +PlayerInfoExplanation=Toggle the miscellaneous player info display. +TargetTracker=Target Tracker +TargetTrackerExplanation=Toggle the target tracker. This displays your score and points relative to a target. +TargetTrackerMode=Target Tracker Mode +TargetTrackerModeExplanation=Toggle the target tracker mode. PB uses your PB unless it is does not exist. Then it falls back to Goal Percent. +TargetTrackerGoal=Target Tracker Goal +TargetTrackerGoalExplanation=Pick a goal percent for the target tracker. +LaneCover=Lane Cover +LaneCoverExplanation=Toggle the lane cover. Hidden is on top of the receptors. Sudden is away from the receptors. +JudgeCounter=Judge Counter +JudgeCounterExplanation=Toggle the judgment counter. +JudgmentText=Judgment Text +JudgmentTextExplanation=Toggle the judgment text. +JudgmentAnimations=Judgment Animations +JudgmentAnimationsExplanation=Toggle the judgment text animations. +ComboTweens=Combo Animations +ComboTweensExplanation=Toggle the combo text animations. +ComboText=Combo Text +ComboTextExplanation=Toggle the combo text. +ComboGlow=Combo Glow +ComboGlowExplanation=Toggle the extra white glow on the Combo numbers during MFCs and PFCs. +ComboLabel=Combo Label +ComboLabelExplanation=Toggle the word 'Combo' as part of the combo text. +CBHighlights=Combo-Breaker Highlights +CBHighlightsExplanation=Toggle showing which column a combo breaker occurs. +MeasureCounter=Measure Counter +MeasureCounterExplanation=Toggle the measure counter. This shows up for longer runs of relatively high NPS. +MeasureLines=Measure Lines +MeasureLinesExplaantion=Toggle showing a line on the NoteField for every measure. +NPSDisplay=NPS Display +NPSDisplayExplanation=Toggle the notes per second display. Displays just NPS and max NPS. +NPSGraph=NPS Graph +NPSGraphExplanation=Toggle the notes per second graph. Displays the NPS over time. +Language=Language +LanguageExplanation=Modify the game language. +Theme=Theme +ThemeExplanation=Change the overall skin of the game. +DisplayMode=Display Mode +DisplayModeExplanation=Change the game display mode. Borderless requires that you select your native fullscreen resolution. +AspectRatio=Aspect Ratio +AspectRatioExplanation=Change the game aspect ratio. +DisplayResolution=Display Resolution +DisplayResolutionExplanation=Change the game display resolution. +RefreshRate=Refresh Rate +RefreshRateExplanation=Change the game refresh rate. Set to default in most cases. Changes the refresh rate, but not the FPS cap. Only applies in exclusive fullscreen. +ColorDepth=Display Color Depth +ColorDepthExplanation=Change the color depth of the game according to your display. Usually not worth changing. +HighResTextures=Force High Resolution Textures +HighResTexturesExplanation=Force high resolution textures. Turning this off disables the (doubleres) image tag. +TextureResolution=Texture Resolution +TextureResolutionExplanation=Modify general texture resolution. Lower number will lower quality but may increase FPS. +VSync=VSync +VSyncExplanation=Restrict the game refresh rate and FPS to the refresh rate you have set. +FastNoteRendering=Fast Note Rendering +FastNoteRenderingExplanation=Optimize gameplay note rendering. Disable snap based noteskin features (not snaps themselves). Major boost to FPS. +ShowStats=Show Stats +ShowStatsExplanation=Show FPS display on screen. +TapGlow=Tap Glow +TapGlowExplanation=Show a white flash before notes disappear when using Hidden or Sudden. +MusicWheelPosition=Music Wheel Position +MusicWheelPositionExplanation=Set the side of the screen for the music wheel. +MusicWheelBanners=Music Wheel Banners +MusicWheelBannersExplanation=Toggle the banners on the music wheel. +VideoBanners=Video Banners +VideoBannersExplanation=Toggle allowing video banners to play at all on the wheel and other locations in music select. +ShowBGs=Show Backgrounds +ShowBGsExplanation=Toggle showing backgrounds everywhere. +ShowBanners=Show Banners +ShowBannersExplanation=Toggle showing banners everywhere. +BGBannerColor=BG Fallback to Banner Color +BGBannerColorExplanation=Toggle using the average color of the pack or song banner when the background is not available. Only applies to music select. +AllowBGChanges=Allow Background Changes +AllowBGChangesExplanation=Toggle gameplay backgrounds changing. +EasterEggs=Easter Eggs & Toasties +EasterEggsExplanation=Toggle showing secret jokes and toasties. +Visualizer=Music Visualizer +VisualizerExplanation=Toggle showing the visualizer in the song select screen. +MidGrades=Mid Grades +MidGradesExplanation=Toggle showing the grades in between the major grades. Requires game restart. +SSRNorm=SSRNorm Sort +SSRNormExplanation=Toggle automatically sorting by and defaulting to the SSRNorm globally. The SSRNorm is the Judge 4 value of a highscore. Requires game restart. +ShowLyrics=Show Lyrics +ShowLyricsExplanation=Toggle showing lyrics for songs which contain compatible .lrc files. +Transliteration=Transliteration +TransliterationExplanation=Toggle showing author-defined translations on song metadata fields. +TipType=Tip Type +TipTypeExplanation=Change the quips shown at the bottom of the evaluation screen. +BGFit=Set BG Fit Mode +BGFitExplanation=Change the cropping strategy of background images. +ColorConfig=Color Config +ColorConfigExplanation=Modify the colors of this theme. +ColorConfigButton=Color Config +AssetSettings=Asset Settings +AssetSettingsExplanation=Set your avatar, judgments, and toasty. +AssetSettingsButton=Asset Settings +Volume=Volume +VolumeExplanation=All sound volume. +MenuSounds=Menu Sounds +MenuSoundsExplanation=Toggle sounds on menu items. +MineSounds=Mine Sounds +MineSoundsExplanation=Toggle sounds for mine explosions. +PitchRates=Pitch on Rates +PitchRatesExplanation=Toggle pitch changes for songs when using rates. +CalibrateAudioSync=Calibrate Audio Sync +CalibrateAudioSyncExplanation=Calibrate the audio sync for the entire game. +CalibrateAudioSyncButton=Calibrate Audio Sync +BackDelayed=Back Delayed +BackDelayedExplanation=Modify the behavior of the back button in gameplay. +StartGiveUp=Hold Start to Give Up +StartGiveUpExplanation=In Gameplay, allow holding Start to fail after holding it for a few seconds. +Debounce=Input Debounce Time +DebounceExplanation=Set the amount of time required between each repeated input. +TestInput=Test Input +TestInputExplanation=Enter a screen to test all input devices. +TestInputButton=Test Input +CreateProfile=Create Profile +CreateProfileExplanation=Create a new profile. +CreateProfileButton=Create Profile +RenameProfile=Rename Profile +RenameProfileExplanation=Rename an existing profile. +RenameProfileButton=Rename Profile [StepsDisplay StepsType] Dance_Single=4K diff --git a/Themes/Rebirth/Languages/ja.ini b/Themes/Rebirth/Languages/ja.ini new file mode 100644 index 0000000000..f37fe5fdac --- /dev/null +++ b/Themes/Rebirth/Languages/ja.ini @@ -0,0 +1,1005 @@ +// snoverpk 23-12-2022 +// 修正: sowasowaさん + +[AssetSettings] +Title=アセット設定 +HoveredItem=Hovered +SelectedItem=Selected +ToastyPageDisplay=トースティ +AvatarPageDisplay=アバター +JudgmentPageDisplay=判定 + +# distinct from the PackDownloader +[BundleDownloader] +Bundle=Bundle +Exit=Exit +Megabytes=MB +KilobytesPerSecond=KB/s +Downloading=Downloading +PacksRemaining=packs remaining +WelcomeInstruction=Welcome to Etterna!\nLet's start by installing some songs. Click the button that corresponds to your skill level and the installation will proceed automatically. +DisconnectedAlert=Server pack listing is empty.\nIs the API down?\nIs your network connection down?\nYou may have to install songs manually. +Novice=Novice +NoviceDescription=A bundle aimed at people who are entirely new to rhythm games.\nMostly single notes throughout the song and very little pattern complexity. +Beginner=Beginner +BeginnerDescription=A bundle for those who have formed some muscle memory.\nJumps (2 note chords) are introduced; some technical patterns start to appear. +Intermediate=Intermediate +IntermediateDescription=A bundle for players who can confidently play complex patterns.\nJumpstream/handstream, very technical patterns, and jacks are common. +Advanced=Advanced +AdvancedDescription=A bundle for advanced players.\nDumps are introduced. Very fast patterns in stamina intensive and complex files. +Expert=Expert +ExpertDescription=A bundle for veterans.\nSome of the hardest songs the game has to offer. Nothing is off-limits. + +[Common] +WindowTitle=Etterna: Rebirth + +[ChordDensityGraph] +NPS=NPS +BPM=BPM + +[ClearTypes] +MFC=MFC +WF=WF +SDP=SDP +PFC=PFC +BF=BF +SDG=SDG +FC=FC +MF=MF +SDCB=SDCB +Clear=Clear +Failed=Failed +Invalid=Invalid +No Play=No Play + +[Header] +LogOut=ログアウト +LogIn=ログイン +Plays=プレイ回数 +ArrowsSmashed=押したノート数 +PlayTime=合計プレイ時間 +PlayerRating=MSDレーティング +PlayerRatings=MSDレーティング +OfflineRating=ローカル +OnlineRating=オンライン +Exit=戻る +Settings=設定 +Help=ヘルプ +Downloads=ダウンロード +Random=ランダム +Search=検索 +DownloadingPacks=ダウンロード中 +QueuedPacks=Queued +UploadPercent=スコアアップロード中 + +[OffsetPlot] +StandardDeviation=SD +Mean=平均 +Time=時間 +Milliseconds=ms +Late=遅い +Early=早い +Instructions=Up/Down for column highlights +CurrentColumnHighlights=Now + +# legacy option names +[OptionNames] +SetPercent=Set Percent +PersonalBest=Personal Best +EWMA=EWMA +NPSDisplay=NPS Display +NPSGraph=NPS Graph + +# legacy option titles +[OptionTitles] +ReceptorSize = Receptor Size +CustomizeGameplay= Customize Gameplay +LaneCover=Lane Cover +StaticBG = Background Changes +CBHighlight=CB Highlight +JudgmentText=Judgment Text +JudgmentAnimations=Judgment Animations +ComboText=Combo Text +ComboLabel=Combo Label +DisplayPercent = Current Percent +TargetTracker = Goal Tracker +TargetGoal = Tracker Goal +TargetTrackerMode = Tracker mode +JudgeCounter = Judge Counter +ErrorBar=Error Bar +ErrorBarCount=Error Bar Count +PlayerInfo = Player Info +FullProgressBar = Full Progressbar +MiniProgressBar = Mini Progressbar +Leaderboard = Leaderboard +NPSDisplay=NPS Display + +# legacy option explanations +[OptionExplanations] +ReceptorSize = Scale the size of the receptors and notes. This will also indirectly scale your scrolling speed. +CustomizeGameplay= While active, allows you to reposition and resize elements on the gameplay screen to your liking. Any changes will persist through version updates. +LaneCover=Enable lane cover which will cover a portion of the notefield. The height can be adjusted by holding down +で調整できます。 +CBHighlight=コンボが切れたレーンを照らす。 +NPSDisplay=Toggle whether to display a flying average NPS display. The time window can be set at Theme Options. +CustomizeGameplay= オンにすると、フィールドの要素を移動することが可能。ゲームアップデートしても初期設定に戻らない。 +CustomEvalWindows= When active, allows you to translate scores at eval screen to custom timing windows/weights. +FadeNoteFieldInSyncMachine= When active, the NoteField in 'Calibrate Audio Sync' will fade after a couple of successful notes to enforce auditory reading for sync adjustment. +Avatars=Set Avatars. This is temporary. +ShowPlayerOptionsHint=Turn this off to disable the bright hint that tells you to press enter to go into Player Options after Select Music. +PONextScreen=次の画面を選択する。 + +DefaultScoreType = Default ScoreType +TipType = Sets the Tiptype to either display tips or random quotes and phrases or nothing at all. + +EvalBGType = Set the type of background to show for ScreenEvaluation. + +Particles = Toggle whether to show particles or not for certain screens. +RateSort = If enabled, the scores will be sorted for different rate mod that was used. +HelpMenu = Toggle whether to automatically display the help menu after a certain period of time has passed. +NPSWindow = Sets the time window (in seconds) of the NPS Display. Smaller window quickly adapts to sudden changes while a larger window gives more stable values. + +MeasureLines=Toggle whether to display measure lines on the notefield. Please reload metrics afterwards. +ProgressBar = Determines the location of the full progress bar during gameplay. +ShowVisualizer=Toggle whether to display the audio visualizer while on the Song Wheel +InstantSearch=Turn this on to have the Song Wheel update for every letter you put into the song search. If you lag when searching, turn this off. +IgnoreTabInput=While on the song wheel, number inputs do not change tabs. +JudgmentTween=Toggle animated judgements. +ComboTween=Toggle combo text animations. +CenteredCombo=Sets the positioning of the combo number (also disables the combo label). + +[OffsetPlot] +ExplainLeft=Highlighting left hand taps +ExplainMiddle=Highlighting middle column taps +ExplainRight=Highlighting right hand taps +ExplainDown=Down toggles highlights +Early=早い +Late=遅い + +[ProfileChanges] +ProfileNameChange = 新しい名前を入力してください: +ProfileNew = Choose a profile display name\nClicking your name will allow you to change it: + +[ChartPreview] +Paused=Paused + +[ChordDensityGraph] +NPS=nps +BPM=bpm + +[CustomizeGameplay] +InstructionAutoplay=Enable AutoplayCPU with Shift+F8\n +InstructionPressKeys=Press keys to toggle active elements +InstructionCancel=Right click cancels any active element\n +JudgmentPosition=Judgment Text Position +JudgmentSize=Judgment Text Size +ComboPosition=Combo Text Position +ComboSize=Combo Text Size +ErrorBarPosition=Error Bar Position +ErrorBarSize=Error Bar Size +TargetTrackerPosition=Target Tracker Position +TargetTrackerSize=Target Tracker Size +FullProgressBarPosition=Full Progress Bar Position +FullProgressBarSize=Full Progress Bar Size +MiniProgressBarPosition=Mini Progress Bar Position +DisplayPercentPosition=Display Percent Text Position +DisplayPercentSize=Display Percent Text Size +NotefieldPosition=Notefield Position +NotefieldSize=Notefield Size +NPSDisplayPosition=NPS Display Text Position +NPSDisplaySize=NPS Display Text Size +NPSGraphPosition=NPS Graph Position +NPSGraphSize=NPS Graph Size +JudgeCounterPosition=Judge Counter Position +LeaderboardPosition=Leaderboard Position +LeaderboardSize=Leaderboard Size +LeaderboardSpacing=Leaderboard Spacing +ReplayButtonPosition=Replay Buttons Position +ReplayButtonSpacing=Replay Buttons Spacing +LifebarPosition=Lifebar Position +LifebarSize=Lifebar Size +LifebarRotation=Lifebar Rotation +LaneCoverHeight=Lane Cover Height +DensityGraphPosition=Density Graph Position +BPMPosition=BPM Text Position +BPMSize=BPM Text Size +RatePosition=Rate Text Position +RateSize=Rate Text Size +NotefieldSpacing=Notefield Columns Spacing + +[ScreenAssetSettings] +Title=アセット設定 +avatar=アバター +judgment=判定 +toasty=トースティ +Selected=Saved +Hovered=Hovered + +[ScreenBundleSelect] +Explanation=Core bundles are diverse selections of packs that span a skill range.\nExpanded sets contain more files and are larger downloads.\nPacks you already have will be skipped +Expanded=expanded +Selected Bundle=Selected Bundle +AverageDiff=Average Difficulty +TotalSize=Total Size +MB=MB +DownloadAll=Download All +GoBack=Return to search + +[ScreenColorChange] +Title=Color Config: +Category=Category: +Name=Name: +Color=Color: + +clearType=Clear Type +BF=Black Flag (BF) +Clear=Clear +FC=Full Combo (FC) +Failed=Failed +Invalid=Invalid +MF=Miss Flag (MF) +MFC=Marvelous Full Combo (MFC) +NoPlay=No Play +None=None +PFC=Perfect Full Combo (PFC) +SDCB=Single Digit Combo Breaker (SDCB) +SDG=Single Digit Greats (SDG) +SDP=Single Digit Perfects (SDP) +WF=White Flag (WF) + +combo=Combo +ComboLabel=Combo Text +FullCombo=Full Combo Numbers +Marv_FullCombo=Marvelous Full Combo Numbers +Perf_FullCombo=Perfect Full Combo Numbers +RegularCombo=Regular Combo Numbers + +difficulty=Difficulty +Beginner=Beginner +Challenge=Challenge +Crazy=Crazy +Difficulty_Beginner=Difficulty_Beginner +Difficulty_Challenge=Difficulty_Challenge +Difficulty_Crazy=Difficulty_Crazy +Difficulty_Easy=Difficulty_Easy +Difficulty_Edit=Difficulty_Edit +Difficulty_Freestyle=Difficulty_Freestyle +Difficulty_Hard=Difficulty_Hard +Difficulty_Medium=Difficulty_Medium +Difficulty_Nightmare=Difficulty_Nightmare +Easy=Easy +Edit=Edit +Freestyle=Freestyle +Hard=Hard +Medium=Medium +Nightmare=Nightmare + +difficultyVivid=Difficulty (Unused) + +grades=Grade +Grade_Failed=Failed +Grade_None=None +Grade_Tier01=AAAAA +Grade_Tier02=AAAA: +Grade_Tier03=AAAA. +Grade_Tier04=AAAA +Grade_Tier05=AAA: +Grade_Tier06=AAA. +Grade_Tier07=AAA +Grade_Tier08=AA: +Grade_Tier09=AA. +Grade_Tier10=AA +Grade_Tier11=A: +Grade_Tier12=A. +Grade_Tier13=A +Grade_Tier14=B +Grade_Tier15=C +Grade_Tier16=D +Grade_Tier17=Grade_Tier17 + +judgment=Judgments +HoldNoteScore_Held=Hold Note Success +HoldNoteScore_LetGo=Hold Note Dropped +TapNoteScore_Miss=Miss +TapNoteScore_W1=Marvelous +TapNoteScore_W2=Perfect +TapNoteScore_W3=Great +TapNoteScore_W4=Good +TapNoteScore_W5=Bad + +laneCover=Lane Cover +cover=Cover Color +bpmText=Cover Calculated BPM Text +heightText=Cover Height Text + +leaderboard=Gameplay Leaderboard +background=Background +border=Border +text=Text + +main=Main Interface +disabled=Disabled/Null/Invalid +enabled=Enabled +frames=Frame Background +tabs=Tabs Background +highlight=Highlights +negative=Negative +positive=Positive + +songLength=Song Length +long=Long +marathon=Marathon +normal=Normal + +title=Title Screen +BG_Left=Left Background +BG_Right=Right Background +Line_Left=Left Line +Line_Right=Right Line + +[ScreenColorEdit] +Title=Color Config: +Description=Press to confirm a typed color. Use to move the cursor\nUse and to reset characters\nPress after confirming or after clicking to save and exit\nPress to exit without saving +AboutToSave=ABOUT TO SAVE +ManualEntry=Manual Entry +Hexadecimal=Hex +RedGreenBlueAlpha=RGBA +Saturation=Sat +Alpha=Alpha +DefaultDescription=Press to select the default color\nPress to undo changes + +[ScreenCoreBundleSelect] +Alert=You have no songs! +Task=Select a skill range to begin downloading some +Explanation=Core bundles are diverse selections of packs that span a skill range. They are chosen based on quality\nand popularity and are intended to span a variety of music and chart types. They will always be \navailable for download in the Packs tab in case you misjudge your level or wish for an easy step up. + +[ScreenEvaluation] +Title=リザルト +ReplayTitle=リプレイリザルト +ChordCohesionOn=CC使用 +MAPARatio=MA:PA比 +Mean=平均 +AbsMean=平均(絶対) +StandardDev=SD +LargestDev=最大 +SmallestDev=最小 +LeftCB=左CB +RightCB=右CB +MiddleCB=中CB + +[ScreenGameplay] +NPSGraphPeakNPS=最大 +NPSGraphNPS=NPS +ButtonPlay=プレイ +ButtonPause=ポーズ +ButtonFastForward=早送り +ButtonRewind=巻き戻す +ErrorBarEarly=早い +ErrorBarLate=遅い +ScoringJudge=Judge +ScoringType=Scoring +ComboText=COMBO +InvalidMods=スコアは無効化されている: + +[ScreenNetRoom] +Title=Lobby + +[ScreenPackDownloader] +Filters=フィルター +AverageDiff=平均難易度(MSD) +Size=サイズ (MB) +BundleSelectEntry=バンドル選択 +CancelCurrentDownload=ダウンロードをキャンセル +SearchingName=名前 +ExplainSizeLimit=2GB以上のパッケージは必ず自分でSongs/に展開してください。 + +[ScreenPlayerOptions] +Title=Player Options +ScrollSpeed='s Scroll Speed + +[ScreenSelectProfile] +Title=Select Profile +PressStartToJoin=Press &START; to join. +SongPlayed=Song Played +SongsPlayed=Songs Played + +[ScreenSystemLayerOverlay] +ItemsDownloading=items currently downloading +ItemsLeftInQueue=items in download queue + +[PacklistDisplay] +Name=名前 +AverageDiff=平均 +Size=サイズ +Installed=インストール済 +Download=ダウンロード +Mirror=ミラー +MB=MB + +[ScreenSelectMusic] +Title=譜面選択 +GoalTargetString=目標 +MaxCombo=最大コンボ +BPM=BPM +NegativeBPM=NegBPM! +TogglePreview=譜面プリビュー +PlayerOptions=プレイヤー設定 +OpenSortMenu=ソートメニューを開く + +[TabNames] +General=詳細 +MSD=MSD +Scores=記録 +Search=検索 +Profile=プロフィール +Filters=フィルター +Goals=ゴール +Playlists=プレイリスト +Packs=パック +Tags=タグ +Chatbox=Chatbox + +[TabMSD] +Title=MSD難易度一覧 +AverageNPS=平均NPS +NegativeBPM=Negative BPMs + +[TabSearch] +Title=Room Search +Active=検索 +Complete=検索が終了しました +ExplainStart=スタートボタンで検索 +ExplainBack=ESCで検索リザルトをリセット +ExplainDelete=デリートキーで検索したテキストを消す +ExplainLimitation=半角英数字のみ +ExplainNumInput=CTRL同時押しで数字をタイプできる (これはテーマ設定で変更できます) +RoomTitle=Title +RoomSubtitle=Desc +RoomOpened=Open +RoomPassworded=Password +RoomInGameplay=Ingame + +[TabScore] +MaxCombo=最大コンボ +ComboBreaks=CB +DateAchieved=達成日 +Mods=設定 +Rate=レート +Showing= +ChordCohesion=Chord Cohesion +ScoreJudge=Judge +NoScores=記録はありません +ShowOffsetPlot=リプレイデータを表示 +NoReplayData=リプレイデータ無し +ShowReplay=リプレイを見る +ShowEval=リザルト画面を見る +UploadReplay=リプレイデータをアップロード +UploadAllScoreChart=この譜面のスコアを全部アップロード +UploadAllScorePack=このパックの譜面のスコアを全部アップロード +UploadAllScore=このプロフィールのスコアを全部アップロード +UploadingReplay=リプレイデータアップロード中... +UploadingScore=スコアデータアップロード中... +NestedLocal=ローカル +NestedOnline=オンライン + +[NestedScores] +LoginToView=オンライン記録を見るのにログインしてください +NoScoresFound=オンライン記録が見つからない... +RetrievingScores=スコア読込中... +FilterAll=すべてのレート +FilterCurrent=現在のレート +ScoresTop=最高記録 +ScoresAll=全部 +ShowInvalid=無効スコアを見る +HideInvalid=無効スコアを無視 +WatchReplay=リプレイを再生 + +[TabProfile] +Title=プロフィール +ScoreValidated=スコア有効化しました +ScoreInvalidated=スコア無効化しました +Online=オンライン +Local=ローカル +Recent=最新 +NextPage=下 +PreviousPage=上 +SaveProfile=プロフィールをセーブ +SaveSuccess=セーブしました。 +SaveFail=セーブ失敗しました。 +AssetSettingEntry=アセット設定 +ValidateAllScores=全部有効化 +ForceRecalcScores=記録再計算 + +[TabFilter] +Title=フィルター(WIP) +ExplainStartInput=左クリックでフィルター数字を設定 +ExplainCancelInput=右クリック/スタート/バックでキャンセル +ExplainGrey=暗い数字は無効 +ExplainBounds=左は最低値で、右は最高値 +ExplainHighest='Highest Skill Only' applies only to Mode: Or +ExplainHighestDifficulty='Highest Diff Only' applies only to Mode: Or +MaxRate=最高レート +MinRate=最低レート +Mode=モード +HighestOnly=最高スキルセットのみ +HighestDifficultyOnly=最難譜面のみ +Matches=該当 +CommonPackFilter=共通パックのみ +Length=長さ(秒) +Reset=リセット +Apply=適用 +AND=ALL +OR=ANY + +[TabGoals] +PriorityLong=優先 +PriorityShort=P +RateLong=レート +RateShort=R +Song=曲名 +Date=日時 +Difficulty=譜面 +Best=自己べ +AssignedDate=指定 +AchievedDate=達成 +VacuousGoal=無駄ゴール +FilterAll=全部 +FilterCompleted=達成 +FilterIncomplete=未達成 + +[TabPlaylists] +Title=プレイリスト +ExplainAddChart=Ctrl+Aで譜面を追加 +ExplainNewPlaylist=Ctrl+Pでプレイリストを作成 +Delete=削除 +PlayAsCourse=コースとしてやる +Back=戻る +Next=下 +Previous=上 +Showing= +ChartCount=譜面数 +AverageRating=平均MSD + +[TabTags] +Title=タグ +AddTag=タグを作成 +ExcludeMode=排除モード +Mode=モード +AND=AND +OR=OR +Next=下 +Previous=上 +Showing= +TagList=タグを追加 +TagFilter=フィルター +TagDelete=タグを削除 + +[Tips] +Title=Help Menu +HowToDisableThis=You can disable this overlay showing up automatically in Theme Options, but it can still be accessed by pressing F12. +HowToHideThis=Press any key to hide this overlay. +Keys=Keys +Buttons=Buttons +Function=Functions +HowToTab=1~0 or clicking the tabs +DescribeTab=Switch to the corresponding tab. (e.g. 3=score, 5=profile, etc.) +HowToAssets=Doubletap +DescribeScoreRatePrevious=While the Score tab is selected, select the previous available rate. +HowToScoreRateNext= while Holding ` tags in the form that you want to fill in. -If there's a "normal" post, you use `-d` to post. `-d` takes a full "post +If there is a "normal" post, you use `-d` to post. `-d` takes a full "post string", which is in the format =&=&... @@ -307,12 +307,14 @@ Example: (page located at `http://www.formpost.com/getthis/`) -
- - - - -
+```html +
+ + + + +
+``` We want to enter user 'foobar' with password '12345'. @@ -371,7 +373,7 @@ allow a user to trick curl into uploading a file. ## Referrer An HTTP request has the option to include information about which address -referred it to the actual page. Curl allows you to specify the referrer to be +referred it to the actual page. curl allows you to specify the referrer to be used on the command line. It is especially useful to fool or trick stupid servers or CGI scripts that rely on that information being available or contain certain data. @@ -417,9 +419,11 @@ the "cookie" should be used for (by specifying `path=value`), when the cookie should expire (`expire=DATE`), for what domain to use it (`domain=NAME`) and if it should be used on secure connections only (`secure`). -If you've received a page from a server that contains a header like: +If you have received a page from a server that contains a header like: - Set-Cookie: sessionid=boo123; path="/foo"; +```http +Set-Cookie: sessionid=boo123; path="/foo"; +``` it means the server wants that first pair passed on when we get anything in a path beginning with "/foo". @@ -441,7 +445,7 @@ cookies from the 'headers' file like: While saving headers to a file is a working way to store cookies, it is however error-prone and not the preferred way to do this. Instead, make curl -save the incoming cookies using the well-known netscape cookie format like +save the incoming cookies using the well-known Netscape cookie format like this: curl -c cookies.txt www.example.com @@ -454,13 +458,13 @@ non-existing file to trigger the cookie awareness like: curl -L -b empty.txt www.example.com The file to read cookies from must be formatted using plain HTTP headers OR as -netscape's cookie file. Curl will determine what kind it is based on the file -contents. In the above command, curl will parse the header and store the -cookies received from www.example.com. curl will send to the server the -stored cookies which match the request as it follows the location. The file +Netscape's cookie file. Curl will determine what kind it is based on the file +contents. In the above command, curl will parse the header and store the +cookies received from www.example.com. curl will send to the server the +stored cookies which match the request as it follows the location. The file "empty.txt" may be a nonexistent file. -To read and write cookies from a netscape cookie file, you can set both `-b` +To read and write cookies from a Netscape cookie file, you can set both `-b` and `-c` to use the same file: curl -b cookies.txt -c cookies.txt www.example.com @@ -490,7 +494,7 @@ From left-to-right: - Curr.Speed - the average transfer speed the last 5 seconds (the first 5 seconds of a transfer is based on less time of course.) -The `-#` option will display a totally different progress bar that doesn't +The `-#` option will display a totally different progress bar that does not need much explanation! ## Speed Limit @@ -505,14 +509,14 @@ second for 1 minute, run: curl -Y 3000 -y 60 www.far-away-site.com -This can very well be used in combination with the overall time limit, so -that the above operation must be completed in whole within 30 minutes: +This can be used in combination with the overall time limit, so that the above +operation must be completed in whole within 30 minutes: curl -m 1800 -Y 3000 -y 60 www.far-away-site.com Forcing curl not to transfer data faster than a given rate is also possible, -which might be useful if you're using a limited bandwidth connection and you -don't want your transfer to use all of it (sometimes referred to as +which might be useful if you are using a limited bandwidth connection and you +do not want your transfer to use all of it (sometimes referred to as "bandwidth throttle"). Make curl transfer data no faster than 10 kilobytes per second: @@ -556,7 +560,7 @@ Example, set default time out and proxy in a config file: # ... and we use a proxy for all accesses: proxy = proxy.our.domain.com:8080 -White spaces ARE significant at the end of lines, but all white spaces leading +Whitespaces ARE significant at the end of lines, but all whitespace leading up to the first characters of each line are ignored. Prevent curl from reading the default file by using -q as the first command @@ -571,7 +575,7 @@ URL by making a config file similar to: url = "http://help.with.curl.com/curlhelp.html" You can specify another config file to be read by using the `-K`/`--config` -flag. If you set config file name to `-` it'll read the config from stdin, +flag. If you set config file name to `-` it will read the config from stdin, which can be handy if you want to hide options from being visible in process tables etc: @@ -579,9 +583,9 @@ tables etc: ## Extra Headers -When using curl in your own very special programs, you may end up needing -to pass on your own custom headers when getting a web page. You can do -this by using the `-H` flag. +When using curl in your own programs, you may end up needing to pass on your +own custom headers when getting a web page. You can do this by using the `-H` +flag. Example, send the header `X-you-and-me: yes` to the server when getting a page: @@ -599,13 +603,13 @@ header from being used: ## FTP and Path Names Do note that when getting files with a `ftp://` URL, the given path is -relative the directory you enter. To get the file `README` from your home +relative to the directory you enter. To get the file `README` from your home directory at your ftp site, do: curl ftp://user:passwd@my.site.com/README -But if you want the README file from the root directory of that very same -site, you need to specify the absolute file name: +If you want the README file from the root directory of that same site, you +need to specify the absolute file name: curl ftp://user:passwd@my.site.com//README @@ -627,13 +631,13 @@ do this. The default way for curl is to issue the PASV command which causes the server to open another port and await another connection performed by the -client. This is good if the client is behind a firewall that doesn't allow +client. This is good if the client is behind a firewall that does not allow incoming connections. curl ftp.download.com -If the server, for example, is behind a firewall that doesn't allow -connections on ports other than 21 (or if it just doesn't support the `PASV` +If the server, for example, is behind a firewall that does not allow +connections on ports other than 21 (or if it just does not support the `PASV` command), the other way to do it is to use the `PORT` command and instruct the server to connect to the client on the given IP number and port (as parameters to the PORT command). @@ -657,11 +661,11 @@ Download with `PORT` but use 192.168.0.10 as our IP address to use: Get a web page from a server using a specified port for the interface: - curl --interface eth0:1 http://www.netscape.com/ + curl --interface eth0:1 http://www.example.com/ or - curl --interface 192.168.1.10 http://www.netscape.com/ + curl --interface 192.168.1.10 http://www.example.com/ ## HTTPS @@ -763,16 +767,16 @@ Authentication support is still missing ## LDAP If you have installed the OpenLDAP library, curl can take advantage of it and -offer `ldap://` support. On Windows, curl will use WinLDAP from Platform SDK +offer `ldap://` support. On Windows, curl will use WinLDAP from Platform SDK by default. -Default protocol version used by curl is LDAPv3. LDAPv2 will be used as -fallback mechanism in case if LDAPv3 will fail to connect. +Default protocol version used by curl is LDAPv3. LDAPv2 will be used as a +fallback mechanism in case LDAPv3 fails to connect. LDAP is a complex thing and writing an LDAP query is not an easy task. I do advise you to dig up the syntax description for that elsewhere. One such place might be: [RFC 2255, The LDAP URL -Format](https://curl.haxx.se/rfc/rfc2255.txt) +Format](https://curl.se/rfc/rfc2255.txt) To show you an example, this is how I can get all people from my local LDAP server that has a certain sub-domain in their email address: @@ -787,7 +791,7 @@ You also can use authentication when accessing LDAP catalog: curl -u user:passwd "ldap://ldap.frontec.se/o=frontec??sub?mail=*" curl "ldap://user:passwd@ldap.frontec.se/o=frontec??sub?mail=*" -By default, if user and password provided, OpenLDAP/WinLDAP will use basic +By default, if user and password are provided, OpenLDAP/WinLDAP will use basic authentication. On Windows you can control this behavior by providing one of `--basic`, `--ntlm` or `--digest` option in curl command line @@ -807,7 +811,7 @@ with ALL_PROXY -A comma-separated list of host names that shouldn't go through any proxy is +A comma-separated list of host names that should not go through any proxy is set in (only an asterisk, `*` matches all hosts) NO_PROXY @@ -826,18 +830,18 @@ The usage of the `-x`/`--proxy` flag overrides the environment variables. Unix introduced the `.netrc` concept a long time ago. It is a way for a user to specify name and password for commonly visited FTP sites in a file so that -you don't have to type them in each time you visit those sites. You realize +you do not have to type them in each time you visit those sites. You realize this is a big security risk if someone else gets hold of your passwords, so -therefore most unix programs won't read this file unless it is only readable -by yourself (curl doesn't care though). +therefore most Unix programs will not read this file unless it is only readable +by yourself (curl does not care though). Curl supports `.netrc` files if told to (using the `-n`/`--netrc` and `--netrc-optional` options). This is not restricted to just FTP, so curl can use it for all protocols where authentication is used. -A very simple `.netrc` file could look something like: +A simple `.netrc` file could look something like: - machine curl.haxx.se login iamdaniel password mysecret + machine curl.se login iamdaniel password mysecret ## Custom Output @@ -860,14 +864,14 @@ Then use curl in way similar to: curl --krb private ftp://krb4site.com -u username:fakepwd -There's no use for a password on the `-u` switch, but a blank one will make +There is no use for a password on the `-u` switch, but a blank one will make curl ask for one and you already entered the real password to kinit/kauth. ## TELNET -The curl telnet support is basic and very easy to use. Curl passes all data -passed to it on stdin to the remote server. Connect to a remote telnet server -using a command line similar to: +The curl telnet support is basic and easy to use. Curl passes all data passed +to it on stdin to the remote server. Connect to a remote telnet server using a +command line similar to: curl telnet://remote.server.com @@ -888,7 +892,7 @@ Other interesting options for it `-t` include: - `NEW_ENV=` Sets an environment variable. NOTE: The telnet protocol does not specify any way to login with a specified -user and password so curl can't do that automatically. To do that, you need to +user and password so curl cannot do that automatically. To do that, you need to track when the login prompt is received and send the username and password accordingly. @@ -905,7 +909,7 @@ better use of the network. Note that curl cannot use persistent connections for transfers that are used in subsequence curl invokes. Try to stuff as many URLs as possible on the same -command line if they are using the same host, as that'll make the transfers +command line if they are using the same host, as that will make the transfers faster. If you use an HTTP proxy for file transfers, practically all transfers will be persistent. @@ -937,7 +941,7 @@ syntax: http://[2001:1890:1112:1::20]/overview.html When this style is used, the `-g` option must be given to stop curl from -interpreting the square brackets as special globbing characters. Link local +interpreting the square brackets as special globbing characters. Link local and site local addresses including a scope identifier, such as `fe80::1234%1`, may also be used, but the scope portion must be numeric or match an existing network interface on Linux and the percent character must be URL escaped. The @@ -948,36 +952,11 @@ previous example in an SFTP URL might look like: IPv6 addresses provided other than in URLs (e.g. to the `--proxy`, `--interface` or `--ftp-port` options) should not be URL encoded. -## Metalink - -Curl supports Metalink (both version 3 and 4 (RFC 5854) are supported), a way -to list multiple URIs and hashes for a file. Curl will make use of the mirrors -listed within for failover if there are errors (such as the file or server not -being available). It will also verify the hash of the file after the download -completes. The Metalink file itself is downloaded and processed in memory and -not stored in the local file system. - -Example to use a remote Metalink file: - - curl --metalink http://www.example.com/example.metalink - -To use a Metalink file in the local file system, use FILE protocol -(`file://`): - - curl --metalink file://example.metalink - -Please note that if FILE protocol is disabled, there is no way to use a local -Metalink file at the time of this writing. Also note that if `--metalink` and -`--include` are used together, `--include` will be ignored. This is because -including headers in the response will break Metalink parser and if the -headers are included in the file described in Metalink file, hash check will -fail. - ## Mailing Lists For your convenience, we have several open mailing lists to discuss curl, its development and things relevant to this. Get all info at -https://curl.haxx.se/mail/. +https://curl.se/mail/. Please direct curl questions, feature requests and trouble reports to one of these mailing lists instead of mailing any individual. @@ -986,7 +965,7 @@ Available lists include: ### curl-users -Users of the command line tool. How to use it, what doesn't work, new +Users of the command line tool. How to use it, what does not work, new features, related tools, questions, news, installations, compilations, running, porting etc. diff --git a/extern/curl/docs/MQTT.md b/extern/curl/docs/MQTT.md new file mode 100644 index 0000000000..0f034f72e4 --- /dev/null +++ b/extern/curl/docs/MQTT.md @@ -0,0 +1,27 @@ +# MQTT in curl + +## Usage + +A plain "GET" subscribes to the topic and prints all published messages. +Doing a "POST" publishes the post data to the topic and exits. + +Example subscribe: + + curl mqtt://host/home/bedroom/temp + +Example publish: + + curl -d 75 mqtt://host/home/bedroom/dimmer + +## What does curl deliver as a response to a subscribe + +It outputs two bytes topic length (MSB | LSB), the topic followed by the +payload. + +## Caveats + +Remaining limitations: + - Only QoS level 0 is implemented for publish + - No way to set retain flag for publish + - No TLS (mqtts) support + - Naive EAGAIN handling will not handle split messages diff --git a/extern/curl/docs/Makefile.am b/extern/curl/docs/Makefile.am index 5ce0d83975..e472565199 100644 --- a/extern/curl/docs/Makefile.am +++ b/extern/curl/docs/Makefile.am @@ -5,11 +5,11 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1998 - 2019, Daniel Stenberg, , et al. +# Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms -# are also available at https://curl.haxx.se/docs/copyright.html. +# are also available at https://curl.se/docs/copyright.html. # # You may opt to use, copy, modify, merge, publish, distribute and/or sell # copies of the Software, and permit persons to whom the Software is @@ -31,7 +31,7 @@ GENHTMLPAGES = curl.html curl-config.html mk-ca-bundle.html PDFPAGES = curl.pdf curl-config.pdf mk-ca-bundle.pdf MANDISTPAGES = curl.1.dist curl-config.1.dist -HTMLPAGES = $(GENHTMLPAGES) index.html +HTMLPAGES = $(GENHTMLPAGES) # Build targets in this file (.) before cmdline-opts to ensure that # the curl.1 rule below runs first @@ -44,48 +44,52 @@ EXTRA_DIST = \ $(noinst_man_MANS) \ ALTSVC.md \ BINDINGS.md \ + BUFREF.md \ BUG-BOUNTY.md \ - BUGS \ + BUGS.md \ CHECKSRC.md \ CIPHERS.md \ CMakeLists.txt \ CODE_OF_CONDUCT.md \ + CODE_REVIEW.md \ CODE_STYLE.md \ CONTRIBUTE.md \ CURL-DISABLE.md \ DEPRECATE.md \ - ESNI.md \ + DYNBUF.md \ EXPERIMENTAL.md \ FAQ \ - FEATURES \ + FEATURES.md \ GOVERNANCE.md \ HELP-US.md \ HISTORY.md \ + HSTS.md \ HTTP-COOKIES.md \ HTTP2.md \ HTTP3.md \ + HYPER.md \ INSTALL \ INSTALL.cmake \ INSTALL.md \ INTERNALS.md \ KNOWN_BUGS \ - LICENSE-MIXING.md \ MAIL-ETIQUETTE \ + MQTT.md \ + NEW-PROTOCOL.md \ + options-in-versions \ PARALLEL-TRANSFERS.md \ - README.cmake \ README.md \ - README.netware \ - README.win32 \ RELEASE-PROCEDURE.md \ - RESOURCES \ + RUSTLS.md \ ROADMAP.md \ SECURITY-PROCESS.md \ SSL-PROBLEMS.md \ SSLCERTS.md \ THANKS \ TODO \ - TheArtOfHttpScripting \ - VERSIONS + TheArtOfHttpScripting.md \ + URL-SYNTAX.md \ + VERSIONS.md MAN2HTML= roffit $< >$@ diff --git a/extern/curl/docs/NEW-PROTOCOL.md b/extern/curl/docs/NEW-PROTOCOL.md new file mode 100644 index 0000000000..9a1451817c --- /dev/null +++ b/extern/curl/docs/NEW-PROTOCOL.md @@ -0,0 +1,110 @@ +# Adding a new protocol? + +Every once in a while someone comes up with the idea of adding support for yet +another protocol to curl. After all, curl already supports 25 something +protocols and it is the Internet transfer machine for the world. + +In the curl project we love protocols and we love supporting many protocols +and doing it well. + +So how do you proceed to add a new protocol and what are the requirements? + +## No fixed set of requirements + +This document is an attempt to describe things to consider. There is no +checklist of the twenty-seven things you need to cross off. We view the entire +effort as a whole and then judge if it seems to be the right thing - for +now. The more things that look right, fit our patterns and are done in ways +that align with our thinking, the better are the chances that we will agree +that supporting this protocol is a grand idea. + +## Mutual benefit is preferred + +curl is not here for your protocol. Your protocol is not here for curl. The +best cooperation and end result occur when all involved parties mutually see +and agree that supporting this protocol in curl would be good for everyone. +Heck, for the world. + +Consider "selling us" the idea that we need an implementation merged in curl, +to be fairly important. *Why* do we want curl to support this new protocol? + +## Protocol requirements + +### Client-side + +The protocol implementation is for a client's side of a "communication +session". + +### Transfer oriented + +The protocol itself should be focused on *transfers*. Be it uploads or +downloads or both. It should at least be possible to view the transfers as +such, like we can view reading emails over POP3 as a download and sending +emails over SMTP as an upload. + +If you cannot even shoehorn the protocol into a transfer focused view, then +you are up for a tough argument. + +### URL + +There should be a documented URL format. If there is an RFC for it there is no +question about it but the syntax does not have to be a published RFC. It could +be enough if it is already in use by other implementations. + +If you make up the syntax just in order to be able to propose it to curl, then +you are in a bad place. URLs are designed and defined for interoperability. +There should at least be a good chance that other clients and servers can be +implemented supporting the same URL syntax and work the same or similar way. + +URLs work on registered 'schemes'. There is a register of [all officially +recognized +schemes](https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml). If +your protocol is not in there, is it really a protocol we want? + +### Wide and public use + +The protocol shall already be used or have an expectation of getting used +widely. Experimental protocols are better off worked on in experiments first, +to prove themselves before they are adopted by curl. + +## Code + +Of course the code needs to be written, provided, licensed agreeably and it +should follow our code guidelines and review comments have to be dealt with. +If the implementation needs third party code, that third party code should not +have noticeably lesser standards than the curl project itself. + +## Tests + +As much of the protocol implementation as possible needs to be verified by +curl test cases. We must have the implementation get tested by CI jobs, +torture tests and more. + +We have experienced many times in the past how new implementations were brought +to curl and immediately once the code had been merged, the originator vanished +from the face of the earth. That is fine, but we need to take the necessary +precautions so when it happens we are still fine. + +Our test infrastructure is powerful enough to test just about every possible +protocol - but it might require a bit of an effort to make it happen. + +## Documentation + +We cannot assume that users are particularly familiar with details and +peculiarities of the protocol. It needs documentation. + +Maybe it even needs some internal documentation so that the developers who +will try to debug something five years from now can figure out functionality a +little easier! + +The protocol specification itself should be freely available without requiring +any NDA or similar. + +## Do not compare + +We are constantly raising the bar and we are constantly improving the +project. A lot of things we did in the past would not be acceptable if done +today. Therefore, you might be tempted to use shortcuts or "hacks" you can +spot other - existing - protocol implementations have used, but there is +nothing to gain from that. The bar has been raised. Former "cheats" will not be +tolerated anymore. diff --git a/extern/curl/docs/PARALLEL-TRANSFERS.md b/extern/curl/docs/PARALLEL-TRANSFERS.md index da688ea050..325e64f9bb 100644 --- a/extern/curl/docs/PARALLEL-TRANSFERS.md +++ b/extern/curl/docs/PARALLEL-TRANSFERS.md @@ -40,7 +40,7 @@ Example: Connections are shared fine between different easy handles, but the "authentication contexts" are not. So for example doing HTTP Digest auth with one handle for a particular transfer and then continue on with another handle -that reuses the same connection, the second handle can't send the necessary +that reuses the same connection, the second handle cannot send the necessary Authorization header at once since the context is only kept in the original easy handle. @@ -49,7 +49,7 @@ share API as well, as a context per origin + path (realm?) basically. Visible in test 153, 1412 and more. -## Feedback! +## Feedback This is early days for parallel transfer support. Keep your eyes open for unintended side effects or downright bugs. diff --git a/extern/curl/docs/README.cmake b/extern/curl/docs/README.cmake deleted file mode 100644 index 084c1de6d5..0000000000 --- a/extern/curl/docs/README.cmake +++ /dev/null @@ -1,16 +0,0 @@ - _ _ ____ _ - ___| | | | _ \| | - / __| | | | |_) | | - | (__| |_| | _ <| |___ - \___|\___/|_| \_\_____| - -README.cmake - Read the README file first. - - Curl contains CMake build files that provide a way to build Curl with the - CMake build tool (www.cmake.org). CMake is a cross platform meta build tool - that generates native makefiles and IDE project files. The CMake build - system can be used to build Curl on any of its supported platforms. - - Read the INSTALL.cmake file for instructions on how to compile curl with - CMake. diff --git a/extern/curl/docs/README.md b/extern/curl/docs/README.md index 6ee42aad33..b72d8bc454 100644 --- a/extern/curl/docs/README.md +++ b/extern/curl/docs/README.md @@ -1,12 +1,12 @@ -![curl logo](https://curl.haxx.se/logo/curl-logo.svg) +![curl logo](https://curl.se/logo/curl-logo.svg) # Documentation -You'll find a mix of various documentation in this directory and +you will find a mix of various documentation in this directory and subdirectories, using several different formats. Some of them are not ideal for reading directly in your browser. -If you'd rather see the rendered version of the documentation, check out the -curl web site's [documentation section](https://curl.haxx.se/docs/) for -general curl stuff or the [libcurl section](https://curl.haxx.se/libcurl/) for +If you would rather see the rendered version of the documentation, check out the +curl website's [documentation section](https://curl.se/docs/) for +general curl stuff or the [libcurl section](https://curl.se/libcurl/) for libcurl related documentation. diff --git a/extern/curl/docs/README.netware b/extern/curl/docs/README.netware deleted file mode 100644 index e6e1e0002e..0000000000 --- a/extern/curl/docs/README.netware +++ /dev/null @@ -1,24 +0,0 @@ - _ _ ____ _ - ___| | | | _ \| | - / __| | | | |_) | | - | (__| |_| | _ <| |___ - \___|\___/|_| \_\_____| - -README.netware - - Read the README file first. - - Curl has been successfully compiled with gcc / nlmconv on different flavours - of Linux as well as with the official Metrowerks CodeWarrior compiler. - While not being the main development target, a continuously growing share of - curl users are NetWare-based, especially also consuming the lib from PHP. - - The unix-style man pages are tricky to read on windows, so therefore all - those pages are also provided as web pages on the curl web site. - - The main curl.1 man page is also "built-in" in the command line tool. Use a - command line similar to this in order to extract a separate text file: - - curl -M >manual.txt - - Read the INSTALL file for instructions on how to compile curl self. diff --git a/extern/curl/docs/README.win32 b/extern/curl/docs/README.win32 deleted file mode 100644 index ca34dd1625..0000000000 --- a/extern/curl/docs/README.win32 +++ /dev/null @@ -1,23 +0,0 @@ - _ _ ____ _ - ___| | | | _ \| | - / __| | | | |_) | | - | (__| |_| | _ <| |___ - \___|\___/|_| \_\_____| - -README.win32 - - Read the README file first. - - Curl has been compiled, built and run on all sorts of Windows and win32 - systems. While not being the main develop target, a fair share of curl users - are win32-based. - - The unix-style man pages are tricky to read on windows, so therefore all - those pages are also provided as web pages on the curl web site. - - The main curl.1 man page is also "built-in" in the command line tool. Use a - command line similar to this in order to extract a separate text file: - - curl -M >manual.txt - - Read the INSTALL file for instructions on how to compile curl self. diff --git a/extern/curl/docs/RELEASE-PROCEDURE.md b/extern/curl/docs/RELEASE-PROCEDURE.md index f2b4343bdd..7e6f305cbd 100644 --- a/extern/curl/docs/RELEASE-PROCEDURE.md +++ b/extern/curl/docs/RELEASE-PROCEDURE.md @@ -4,6 +4,8 @@ curl release procedure - how to do a release in the source code repo ----------------------- +- run `./scripts/copyright.pl` and correct possible omissions + - edit `RELEASE-NOTES` to be accurate - update `docs/THANKS` @@ -40,9 +42,9 @@ in the curl-www repo - make sure all relevant changes are committed and pushed on the master branch - (the web site then updates its contents automatically) + (the website then updates its contents automatically) -on github +on GitHub --------- - edit the newly made release tag so that it is listed as the latest release @@ -93,14 +95,12 @@ Coming dates Based on the description above, here are some planned release dates (at the time of this writing): -- March 4, 2020 (7.69.0) -- April 29, 2020 -- June 24, 2020 -- August 19, 2020 -- October 14, 2020 -- December 9, 2020 -- February 3, 2021 - -The above (and more) curl-related dates are published in -[iCalendar format](https://calendar.google.com/calendar/ical/c9u5d64odop9js55oltfarjk6g%40group.calendar.google.com/public/basic.ics) -as well. +- May 11, 2022 (7.83.1) +- July 6, 2022 +- August 31, 2022 +- October 25, 2022 +- December 21, 2022 +- February 15, 2023 (last version 7 release, no feature window after) +- March 20, 2023 (8.0.0 - curl 25 years) +- April 17, 2023 +- July 12, 2023 diff --git a/extern/curl/docs/RESOURCES b/extern/curl/docs/RESOURCES deleted file mode 100644 index 55f75df770..0000000000 --- a/extern/curl/docs/RESOURCES +++ /dev/null @@ -1,85 +0,0 @@ - _ _ ____ _ - Project ___| | | | _ \| | - / __| | | | |_) | | - | (__| |_| | _ <| |___ - \___|\___/|_| \_\_____| - - -This document lists documents and standards used by curl. - - RFC 959 - FTP Protocol - - RFC 1635 - How to Use Anonymous FTP - - RFC 1738 - Uniform Resource Locators - - RFC 1777 - Lightweight Directory Access Protocol (LDAP) - - RFC 1808 - Relative Uniform Resource Locators - - RFC 1867 - Form-based File Upload in HTML - - RFC 1950 - ZLIB Compressed Data Format Specification - - RFC 1951 - DEFLATE Compressed Data Format Specification - - RFC 1952 - GZIP File Format Specification - - RFC 1959 - LDAP URL Syntax - - RFC 2045-2049 - Everything you need to know about MIME! (needed for form - based upload) - - RFC 2068 - HTTP 1.1 (obsoleted by RFC 2616) - - RFC 2104 - Keyed-Hashing for Message Authentication - - RFC 2109 - HTTP State Management Mechanism (cookie stuff) - - Also, read Netscape's specification at - https://curl.haxx.se/rfc/cookie_spec.html - - RFC 2183 - The Content-Disposition Header Field - - RFC 2195 - CRAM-MD5 Authentication - - RFC 2229 - A Dictionary Server Protocol - - RFC 2255 - Newer LDAP URL Format - - RFC 2231 - MIME Parameter Value and Encoded Word Extensions: - Character Sets, Languages, and Continuations - - RFC 2388 - "Returning Values from Forms: multipart/form-data" - Use this as an addition to the RFC1867 - - RFC 2396 - "Uniform Resource Identifiers: Generic Syntax and Semantics" This - one obsoletes RFC 1738, but since RFC 1738 is often mentioned - I've left it in this list. - - RFC 2428 - FTP Extensions for IPv6 and NATs - - RFC 2577 - FTP Security Considerations - - RFC 2616 - HTTP 1.1, the latest - - RFC 2617 - HTTP Authentication - - RFC 2718 - Guidelines for new URL Schemes - - RFC 2732 - Format for Literal IPv6 Addresses in URL's - - RFC 2818 - HTTP Over TLS (TLS is the successor to SSL) - - RFC 2821 - Simple Mail Transfer Protocol (SMTP) - - RFC 2964 - Use of HTTP State Management - - RFC 2965 - HTTP State Management Mechanism. Cookies. Obsoletes RFC2109 - - RFC 3207 - SMTP Over TLS - - RFC 4616 - PLAIN Authentication - - RFC 4954 - SMTP Authentication - - RFC 7932 - Brotli Compressed Data Format diff --git a/extern/curl/docs/ROADMAP.md b/extern/curl/docs/ROADMAP.md index 7bd07196ff..e48c21b58d 100644 --- a/extern/curl/docs/ROADMAP.md +++ b/extern/curl/docs/ROADMAP.md @@ -1,63 +1,24 @@ -curl the next few years - perhaps -================================= +# curl the next few years - perhaps Roadmap of things Daniel Stenberg wants to work on next. It is intended to serve as a guideline for others for information, feedback and possible participation. -HSTS ----- +## "Complete" the HTTP/3 support - Complete and merge [the existing PR](https://github.com/curl/curl/pull/2682). +curl has experimental support for HTTP/3 since a good while back. There are +some functionality missing and once the final specs are published we want to +eventually remove the "experimental" label from this functionality. - Loading a huge preload file is probably not too interesting to most people, - but using a custom file and reacting to HSTS response header probably are - good features. +## HTTPS DNS records -DNS-over-TLS ------------- +As a DNS version of alt-svc and also a pre-requisite for ECH (see below). - Similar to DNS-over-HTTPS. Could share quite a lot of generic code. +See: https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-02 -ESNI (Encrypted SNI) --------------------- +## ECH (Encrypted Client Hello - formerly known as ESNI) See Daniel's post on [Support of Encrypted - SNI](https://curl.haxx.se/mail/lib-2019-03/0000.html) on the mailing list. + SNI](https://curl.se/mail/lib-2019-03/0000.html) on the mailing list. Initial work exists in https://github.com/curl/curl/pull/4011 - -thread-safe `curl_global_init()` --------------------------------- - - Fix the libcurl specific parts of the function to be thread-safe. Make sure - it can be thread-safe if built with thread-safe 3rd party libraries. - (probably can't include `curl_global_init_mem()` for obvious reasons) - -tiny-curl ---------- - - There's no immediate action for this but users seem keen on being able to - building custom minimized versions of libcurl for their products. Make sure - new features that are "niche" can still be disabled at build-time. - -MQTT ----- - - Support receiving and sending MQTT messages. Initial work exists in - https://github.com/curl/curl/pull/3514 - -Hardcode “localhost” --------------------- - - No need to resolve it. Avoid a risk where this is resolved over the network - and actually responds with something else than a local address. Some - operating systems already do this. Also: - https://tools.ietf.org/html/draft-ietf-dnsop-let-localhost-be-localhost-02 - -"menu config"-style build feature selection -------------------------------------------- - - Allow easier building of custom libcurl versions with only a selected feature - where the available features are easily browsable and toggle-able ON/OFF or - similar. diff --git a/extern/curl/docs/RUSTLS.md b/extern/curl/docs/RUSTLS.md new file mode 100644 index 0000000000..4b49b5cf79 --- /dev/null +++ b/extern/curl/docs/RUSTLS.md @@ -0,0 +1,26 @@ +# Rustls + +[Rustls is a TLS backend written in Rust.](https://docs.rs/rustls/). Curl can +be built to use it as an alternative to OpenSSL or other TLS backends. We use +the [rustls-ffi C bindings](https://github.com/rustls/rustls-ffi/). This +version of curl depends on version v0.8.2 of rustls-ffi. + +# Building with rustls + +First, [install Rust](https://rustup.rs/). + +Next, check out, build, and install the appropriate version of rustls-ffi: + + % cargo install cbindgen + % git clone https://github.com/rustls/rustls-ffi -b v0.8.2 + % cd rustls-ffi + % make + % make DESTDIR=${HOME}/rustls-ffi-built/ install + +Now configure and build curl with rustls: + + % git clone https://github.com/curl/curl + % cd curl + % autoreconf -fi + % ./configure --with-rustls=${HOME}/rustls-ffi-built + % make diff --git a/extern/curl/docs/SECURITY-PROCESS.md b/extern/curl/docs/SECURITY-PROCESS.md index e844a9a90f..a7e86615c4 100644 --- a/extern/curl/docs/SECURITY-PROCESS.md +++ b/extern/curl/docs/SECURITY-PROCESS.md @@ -1,25 +1,22 @@ -curl security process -===================== +# curl security process This document describes how security vulnerabilities should be handled in the curl project. -Publishing Information ----------------------- +## Publishing Information All known and public curl or libcurl related vulnerabilities are listed on -[the curl web site security page](https://curl.haxx.se/docs/security.html). +[the curl website security page](https://curl.se/docs/security.html). Security vulnerabilities **should not** be entered in the project's public bug tracker. -Vulnerability Handling ----------------------- +## Vulnerability Handling The typical process for handling a new security vulnerability is as follows. No information should be made public about a vulnerability until it is -formally announced at the end of this process. That means, for example that a +formally announced at the end of this process. That means, for example, that a bug tracker entry must NOT be created to track the issue since that will make the issue public and it should not be discussed on any of the project's public mailing lists. Also messages associated with any commits should not make any @@ -38,7 +35,8 @@ announcement. that a human has seen the report. - The security team investigates the report and either rejects it or accepts - it. + it. See below for examples of problems that are not considered + vulnerabilities. - If the report is rejected, the team writes to the reporter to explain why. @@ -62,19 +60,20 @@ announcement. - Request a CVE number from [HackerOne](https://docs.hackerone.com/programs/cve-requests.html) -- Consider informing - [distros@openwall](https://oss-security.openwall.org/wiki/mailing-lists/distros) - to prepare them about the upcoming public security vulnerability - announcement - attach the advisory draft for information. Note that - 'distros' won't accept an embargo longer than 14 days and they do not care - for Windows-specific flaws. - - Update the "security advisory" with the CVE number. - The security team commits the fix in a private branch. The commit message - should ideally contain the CVE number. This fix is usually also distributed - to the 'distros' mailing list to allow them to use the fix prior to the - public announcement. + should ideally contain the CVE number. + +- The security team also decides on and delivers a monetary reward to the + reporter as per the bug-bounty policies. + +- No more than 10 days before release, inform + [distros@openwall](https://oss-security.openwall.org/wiki/mailing-lists/distros) + to prepare them about the upcoming public security vulnerability + announcement - attach the advisory draft for information with CVE and + current patch. 'distros' does not accept an embargo longer than 14 days and + they do not care for Windows-specific flaws. - No more than 48 hours before the release, the private branch is merged into the master branch and pushed. Once pushed, the information is accessible to @@ -88,27 +87,25 @@ announcement. the same manner we always announce releases. It gets sent to the curl-announce, curl-library and curl-users mailing lists. -- The security web page on the web site should get the new vulnerability +- The security web page on the website should get the new vulnerability mentioned. -curl-security (at haxx dot se) ------------------------------- +## security (at curl dot se) This is a private mailing list for discussions on and about curl security issues. Who is on this list? There are a couple of criteria you must meet, and then we -might ask you to join the list or you can ask to join it. It really isn't very -formal. We basically only require that you have a long-term presence in the -curl project and you have shown an understanding for the project and its way -of working. You must've been around for a good while and you should have no -plans in vanishing in the near future. +might ask you to join the list or you can ask to join it. It really is not a +formal process. We basically only require that you have a long-term presence +in the curl project and you have shown an understanding for the project and +its way of working. You must have been around for a good while and you should +have no plans of vanishing in the near future. We do not make the list of participants public mostly because it tends to vary somewhat over time and a list somewhere will only risk getting outdated. -Publishing Security Advisories ------------------------------- +## Publishing Security Advisories 1. Write up the security advisory, using markdown syntax. Use the same subtitles as last time to maintain consistency. @@ -118,15 +115,100 @@ Publishing Security Advisories 3. Add a line on the top of the array in `curl-www/docs/vuln.pm'. 4. Put the new advisory markdown file in the curl-www/docs/ directory. Add it - to the git repo. + to the git repository. 5. Run `make` in your local web checkout and verify that things look fine. 6. On security advisory release day, push the changes on the curl-www repository's remote master branch. -Bug Bounty ----------- +## Hackerone + +Request the issue to be disclosed. If there are sensitive details present in +the report and discussion, those should be redacted from the disclosure. The +default policy is to disclose as much as possible as soon as the vulnerability +has been published. -See [BUG-BOUNTY](https://curl.haxx.se/docs/bugbounty.html) for details on the +## Bug Bounty + +See [BUG-BOUNTY](https://curl.se/docs/bugbounty.html) for details on the bug bounty program. + +# Not security issues + +This is an incomplete list of issues that are not considered vulnerabilities. + +## Small memory leaks + +We do not consider a small memory leak a security problem; even if the amount +of allocated memory grows by a small amount every now and then. Long-living +applications and services already need to have counter-measures and deal with +growing memory usage, be it leaks or just increased use. A small memory or +resource leak is then expected to *not* cause a security problem. + +Of course there can be a discussion if a leak is small or not. A large leak +can be considered a security problem due to the DOS risk. If leaked memory +contains sensitive data it might also qualify as a security problem. + +## Never-ending transfers + +We do not consider flaws that cause a transfer to never end to be a security +problem. There are already several benign and likely reasons for transfers to +stall and never end, so applications that cannot deal with never-ending +transfers already need to have counter-measures established. + +If the problem avoids the regular counter-measures when it causes a never- +ending transfer, it might very well be a security problem. + +## Not practically possible + +If the flaw or vulnerability cannot practically get executed on existing +hardware it is not a security problem. + +## API misuse + +If a reported issue only triggers by an application using the API in a way +that is not documented to work or even documented to not work, it is probably +not going to be considered a security problem. We only guarantee secure and +proper functionality when the APIs are used as expected and documented. + +There can be a discussion about what the documentation actually means and how +to interpret the text, which might end up with us still agreeing that it is a +security problem. + +## Local attackers already present + +When an issue can only be attacked or misused by an attacker present on the +local system or network, the bar is raised. If a local user wrongfully has +elevated rights on your system enough to attack curl, they can probably +already do much worse harm and the problem is not really in curl. + +## Experiments + +Vulnerabilities in features which are off by default (in the build) and +documented as experimental, are not eligible for a reward and we do not +consider them security problems. + +## URL inconsistencies + +URL parser inconsistencies between browsers and curl are expected and are not +considered security vulnerabilities. The WHATWG URL Specification and RFC +3986+ (the plus meaning that it is an extended version) [are not completely +interoperable](https://github.com/bagder/docs/blob/master/URL-interop.md). + +Obvious parser bugs can still be vulnerabilities of course. + +## Visible command line arguments + +The curl command blanks the contents of a number of command line arguments to +prevent them from appearing in process listings. It does not blank all +arguments even if some of them that are not blanked might contain sensitive +data. We consider this functionality a best-effort and omissions are not +security vulnerabilities. + + - not all systems allow the arguments to be blanked in the first place + - since curl blanks the argument itself they will be readable for a short + moment in time no matter what + - virtually every argument can contain sensitive data, depending on use + - blanking all arguments would make it impractical for users to differentiate + curl command lines in process listings diff --git a/extern/curl/docs/SSL-PROBLEMS.md b/extern/curl/docs/SSL-PROBLEMS.md index aaf7bdb594..4afe300189 100644 --- a/extern/curl/docs/SSL-PROBLEMS.md +++ b/extern/curl/docs/SSL-PROBLEMS.md @@ -11,7 +11,7 @@ ago. There are several known reasons why a connection that involves SSL might - fail. This is a document that attempts to details the most common ones and + fail. This is a document that attempts to detail the most common ones and how to mitigate them. ## CA certs @@ -23,8 +23,18 @@ ## CA bundle missing intermediate certificates When using said CA bundle to verify a server cert, you will experience - problems if your CA cert does not have the certificates for the - intermediates in the whole trust chain. + problems if your CA store does not contain the certificates for the + intermediates if the server does not provide them. + + The TLS protocol mandates that the intermediate certificates are sent in the + handshake, but as browsers have ways to survive or work around such + omissions, missing intermediates in TLS handshakes still happen that + browser-users will not notice. + + Browsers work around this problem in two ways: they cache intermediate + certificates from previous transfers and some implement the TLS "AIA" + extension that lets the client explicitly download such certificates on + demand. ## Protocol version @@ -36,11 +46,12 @@ An additional complication can be that modern SSL libraries sometimes are built with support for older SSL and TLS versions disabled! - All versions of SSL are considered insecure and should be avoided. Use TLS. + All versions of SSL and the TLS versions before 1.2 are considered insecure + and should be avoided. Use TLS 1.2 or later. ## Ciphers - Clients give servers a list of ciphers to select from. If the list doesn't + Clients give servers a list of ciphers to select from. If the list does not include any ciphers the server wants/can use, the connection handshake fails. @@ -59,13 +70,13 @@ References: - https://tools.ietf.org/html/draft-popov-tls-prohibiting-rc4-01 + https://datatracker.ietf.org/doc/html/draft-popov-tls-prohibiting-rc4-01 ## Allow BEAST BEAST is the name of a TLS 1.0 attack that surfaced 2011. When adding means to mitigate this attack, it turned out that some broken servers out there in - the wild didn't work properly with the BEAST mitigation in place. + the wild did not work properly with the BEAST mitigation in place. To make such broken servers work, the --ssl-allow-beast option was introduced. Exactly as it sounds, it re-introduces the BEAST vulnerability @@ -78,10 +89,10 @@ depending on the OS or build configuration. The --ssl-no-revoke option was introduced in 7.44.0 to disable revocation checking but currently is only supported for Schannel (the native Windows SSL library), with an exception - in the case of Windows' Untrusted Publishers blacklist which it seems can't + in the case of Windows' Untrusted Publishers block list which it seems cannot be bypassed. This option may have broader support to accommodate other SSL backends in the future. References: - https://curl.haxx.se/docs/ssl-compared.html + https://curl.se/docs/ssl-compared.html diff --git a/extern/curl/docs/SSLCERTS.md b/extern/curl/docs/SSLCERTS.md index 2c5be68e6a..ec57f41c9d 100644 --- a/extern/curl/docs/SSLCERTS.md +++ b/extern/curl/docs/SSLCERTS.md @@ -13,8 +13,8 @@ Native SSL If libcurl was built with Schannel or Secure Transport support (the native SSL libraries included in Windows and Mac OS X), then this does not apply to you. Scroll down for details on how the OS-native engines handle SSL -certificates. If you're not sure, then run "curl -V" and read the results. If -the version string says "WinSSL" in it, then it was built with Schannel +certificates. If you are not sure, then run "curl -V" and read the results. If +the version string says `Schannel` in it, then it was built with Schannel support. It is about trust @@ -22,19 +22,19 @@ It is about trust This system is about trust. In your local CA certificate store you have certs from *trusted* Certificate Authorities that you then can use to verify that the -server certificates you see are valid. They're signed by one of the CAs you +server certificates you see are valid. they are signed by one of the CAs you trust. Which CAs do you trust? You can decide to trust the same set of companies your -operating system trusts, or the set one of the known browsers trust. That's +operating system trusts, or the set one of the known browsers trust. That is basically trust via someone else you trust. You should just be aware that modern operating systems and browsers are setup to trust *hundreds* of -companies and recent years several such CAs have been found untrustworthy. +companies and in recent years several such CAs have been found untrustworthy. Certificate Verification ------------------------ -libcurl performs peer SSL certificate verification by default. This is done +libcurl performs peer SSL certificate verification by default. This is done by using a CA certificate store that the SSL library can use to make sure the peer's server certificate is valid. @@ -42,8 +42,8 @@ If you communicate with HTTPS, FTPS or other TLS-using servers using certificates that are signed by CAs present in the store, you can be sure that the remote server really is the one it claims to be. -If the remote server uses a self-signed certificate, if you don't install a CA -cert store, if the server uses a certificate signed by a CA that isn't +If the remote server uses a self-signed certificate, if you do not install a CA +cert store, if the server uses a certificate signed by a CA that is not included in the store you use or if the remote host is an impostor impersonating your favorite site, and you want to transfer files from this server, do one of the following: @@ -55,16 +55,16 @@ server, do one of the following: 2. Get a CA certificate that can verify the remote server and use the proper option to point out this CA cert for verification when connecting. For - libcurl hackers: `curl_easy_setopt(curl, CURLOPT_CAPATH, capath);` + libcurl hackers: `curl_easy_setopt(curl, CURLOPT_CAINFO, cacert);` With the curl command line tool: --cacert [file] 3. Add the CA cert for your server to the existing default CA certificate - store. The default CA certificate store can changed at compile time with the - following configure options: + store. The default CA certificate store can be changed at compile time with + the following configure options: - --with-ca-bundle=FILE: use the specified file as CA certificate store. CA - certificates need to be concatenated in PEM format into this file. + --with-ca-bundle=FILE: use the specified file as the CA certificate store. + CA certificates need to be concatenated in PEM format into this file. --with-ca-path=PATH: use the specified path as CA certificate store. CA certificates need to be stored as individual PEM files in this directory. @@ -103,11 +103,11 @@ server, do one of the following: certificate store or use it stand-alone as described. Just remember that the security is no better than the way you obtained the certificate. - 4. If you're using the curl command line tool, you can specify your own CA - cert path by setting the environment variable `CURL_CA_BUNDLE` to the path + 4. If you are using the curl command line tool, you can specify your own CA + cert file by setting the environment variable `CURL_CA_BUNDLE` to the path of your choice. - If you're using the curl command line tool on Windows, curl will search + If you are using the curl command line tool on Windows, curl will search for a CA cert file named "curl-ca-bundle.crt" in these directories and in this order: 1. application's directory @@ -119,10 +119,10 @@ server, do one of the following: 5. Get a better/different/newer CA cert bundle! One option is to extract the one a recent Firefox browser uses by running 'make ca-bundle' in the curl build tree root, or possibly download a version that was generated this - way for you: [CA Extract](https://curl.haxx.se/docs/caextract.html) + way for you: [CA Extract](https://curl.se/docs/caextract.html) Neglecting to use one of the above methods when dealing with a server using a -certificate that isn't signed by one of the certificates in the installed CA +certificate that is not signed by one of the certificates in the installed CA certificate store, will cause SSL to report an error ("certificate verify failed") during the handshake and SSL will then refuse further communication with that server. diff --git a/extern/curl/docs/THANKS b/extern/curl/docs/THANKS index 53735cb6f5..e3a2ff5867 100644 --- a/extern/curl/docs/THANKS +++ b/extern/curl/docs/THANKS @@ -4,13 +4,20 @@ If you have contributed but are missing here, please let us know! +0xee on github +0xflotus on github +1337vt on github 1ocalhost on github 3dyd on github +3eka on github +8U61ife on github +a1346054 on github Aaro Koskinen Aaron Oneal Aaron Orenstein Aaron Scarisbrick aasivov on github +Abhinav Singh Abram Pousada accountantM on github AceCrow on Github @@ -22,8 +29,10 @@ Adam Langley Adam Light Adam Marcionek Adam Piggott +Adam Rosenfield Adam Sampson Adam Tkac +Adnan Khan adnn on github Adrian Burcea Adrian Peniak @@ -37,13 +46,18 @@ Aki Koskinen Akos Pasztory Akshay Vernekar Alain Danteny +Alain Miniussi Alan Jenkins Alan Pinstein Albert Chin-A-Young Albert Choy +Albin Vass Alejandro Alvarez Ayllon +Alejandro Colomar Alejandro R. Sedeño Aleksandar Milivojevic +Aleksander Mazur +Aleksandr Krotov Aleksey Tulinov Ales Mlakar Ales Novak @@ -53,9 +67,12 @@ Alex aka WindEagle Alex Baines Alex Bligh Alex Chan +Alex Crichton Alex Fishman +Alex Gaynor Alex Grebenschikov Alex Gruz +Alex Kiernan Alex Konev Alex Malinovich Alex Mayorga @@ -67,9 +84,12 @@ Alex Rousskov Alex Samorukov Alex Suykov Alex Vinnik +Alex Xu Alexander Beedie +Alexander Chuykov Alexander Dyagilev Alexander Elgert +Alexander Kanavin Alexander Klauer Alexander Kourakos Alexander Krasnostavsky @@ -78,7 +98,9 @@ Alexander Pepper Alexander Peslyak Alexander Sinditskiy Alexander Traud +Alexander V. Tikhonov Alexander Zhuravlev +Alexandre Pion Alexey Borzov Alexey Eremikhin Alexey Melnichuk @@ -87,10 +109,12 @@ Alexey Simak Alexey Zakhlestin Alexis Carvalho Alexis La Goutte +Alexis Vachette Alfonso Martone Alfred Gebert Allen Pulsifer Alona Rossen +Amaury Denoyelle amishmm on github Amit Katyal Amol Pattekar @@ -107,9 +131,11 @@ Anderson Toshiyuki Sasaki Andi Jahja Andre Guibert de Bruet Andre Heinecke +Andrea Pappacoda Andreas Damm Andreas Falkenhahn Andreas Farber +Andreas Fischer Andreas Kostyrka Andreas Malzahn Andreas Ntaflos @@ -121,14 +147,18 @@ Andreas Schuldei Andreas Streichardt Andreas Wurf Andrei Benea +Andrei Bica Andrei Cipu Andrei Karas Andrei Kurushin Andrei Neculau +Andrei Rybak Andrei Sedoi Andrei Valeriu BICA Andrei Virtosu Andrej E Baranov +Andrew Barnert +Andrew Barnes Andrew Benham Andrew Biggs Andrew Bushnell @@ -143,6 +173,8 @@ Andrew Moise Andrew Potter Andrew Robbins Andrew Wansink +Andrey Alifanov +Andrey Gursky Andrey Labunets Andrii Moiseiev Andrius Merkys @@ -152,13 +184,20 @@ Andy Fiddaman Andy Serpa Andy Tsouladze Angus Mackay +anio on github +anon00000000 on github anshnd on github +Antarpreet Singh Anthon Pang Anthony Avina Anthony Bryan Anthony G. Basile +Anthony Hu +Anthony Ramine +Anthony Shaw Antoine Aubert Antoine Calando +Antoine Pietri Anton Bychkov Anton Gerasimov Anton Kalmykov @@ -168,6 +207,7 @@ Antoni Villalonga Antonio Larrosa Antony74 on github Antti Hätälä +April King arainchik on github Archangel_SDY on github Arkadiusz Miskiewicz @@ -179,32 +219,45 @@ Aron Bergman Aron Rotteveel Artak Galoyan Arthur Murray +Artur Sinila Arve Knudsen Arvid Norberg +arvids-kokins-bidstack on github asavah on github Ashish Shukla +Ashwin Metpalli Ask Bjørn Hansen Askar Safin Ates Goral Augustus Saunders Austin Green Avery Fay +awesomenode on github +Axel Chong +Axel Morawietz Axel Tillequin Ayoub Boudhar +Ayushman Singh Chauhan +b9a1 on github +Bachue Zhou Balaji Parasuram Balaji S Rao Balaji Salunke +Balakrishnan Balasubramanian Balazs Kovacsics Balint Szilakszi Barry Abrahamson Barry Pollard Bart Whiteley +Baruch Siach Bas Mevissen Bas van Schaik +Bastian Krause Bastien Bouclet Basuke Suzuki baumanj on github bdry on github +beckenc on github Ben Boeckel Ben Darnell Ben Greear @@ -214,17 +267,20 @@ Ben Noordhuis Ben Van Hof Ben Voris Ben Winslow +Benau on github Benbuck Nason Benjamin Gerard Benjamin Gilbert Benjamin Johnson Benjamin Kircher +Benjamin Riefenstahl Benjamin Ritcey Benjamin Sergeant Benoit Neil Benoit Sigoure Bernard Leak Bernard Spil +Bernat Mut Bernd Mueller Bernhard Iselborn Bernhard M. Wiedemann @@ -233,12 +289,18 @@ Bernhard Walle Bert Huijben Bertrand Demiddelaer Bertrand Simonnet +beslick5 on github +Bevan Weiss Bill Doyle Bill Egert Bill Hoffman Bill Middlecamp Bill Nagel Bill Pyne +billionai on github +Billyzou0741326 on github +Bin Lan +Bin Meng Bjarni Ingi Gislason Bjoern Franke Bjoern Sikora @@ -246,12 +308,17 @@ Bjorn Augustsson Bjorn Reese Björn Stenberg Blaise Potard +Blake Burkhart bnfp on github +Bo Anderson Bob Relyea Bob Richmond Bob Schader bobmitchell1956 on github +Bodo Bergmann Bogdan Nicula +Boris Rasin +Boris Verkhovskiy Brad Burdick Brad Fitzpatrick Brad Harder @@ -266,12 +333,14 @@ Brandon Wang Brendan Jurd Brent Beardsley Brian Akins +Brian Bergeron Brian Carpenter Brian Chaplin Brian Childs Brian Chrisman Brian Dessent Brian E. Gallew +Brian Inglis Brian J. Murrell Brian Prodoehl Brian R Duffy @@ -280,23 +349,31 @@ Brock Noland Bru Rom Bruce Mitchener Bruce Stephens +BrumBrum on hackerone +Bruno Baguette Bruno de Carvalho Bruno Grasselli Bruno Thomsen Bryan Henderson Bryan Kemp bsammon on github +Bubu on github buzo-ffm on github bxac on github Bylon2 on github Byrial Jensen Caleb Raitto +Calvin Buckley +Cameron Cawley Cameron Kaiser Cameron MacMinn +Cameron Will Camille Moncelier +Cao ZhenXiang Caolan McNamara Captain Basil Carie Pointer +Carl Zogheib Carlo Cannas Carlo Marcelo Arenas Belón Carlo Teubner @@ -305,13 +382,17 @@ Carlos ORyan Carsten Lange Casey O'Donnell Catalin Patulea +causal-agent on github cbartl on github cclauss on github +Cesar Eduardo Barros Chad Monroe Chandrakant Bagul +Charles Cazabon Charles Kerr Charles Romestant Chen Prog +Cherish98 on github Chester Liu Chih-Chung Chang Chih-Hsuan Yen @@ -326,6 +407,8 @@ Chris Flerackers Chris Gaukroger Chris Maltby Chris Mumford +Chris Paulson-Ellis +Chris Roberts Chris Smowton Chris Young Christian Fillion @@ -339,11 +422,13 @@ Christian Schmitz Christian Stewart Christian Vogt Christian Weisgerber +Christoph Krey Christoph M. Becker Christophe Demory Christophe Dervieux Christophe Legry Christopher Conroy +Christopher Degawa Christopher Head Christopher Palow Christopher R. Palmer @@ -351,6 +436,7 @@ Christopher Reid Christopher Stone Chungtsun Li Ciprian Badescu +civodul on github Claes Jakobsson Clarence Gardner Claudio Neves @@ -364,12 +450,17 @@ cmfrolick on github codesniffer13 on github Cody Jones Cody Mack +COFFEETALES on github +coinhubs on github Colby Ranger Colin Blair Colin Hogben +Colin Leroy +Colin O'Dell Colin Watson Colm Buckley Constantine Sapuntzakis +coralw on github Cory Benfield Cory Nelson Costya Shulyupin @@ -381,6 +472,7 @@ Craig Markwardt crazydef on github Cris Bailiff Cristian Greco +Cristian Morales Vega Cristian Rodríguez Curt Bogmine Cynthia Coan @@ -389,22 +481,26 @@ Cyrill Osterwalder Cédric Connes Cédric Deltheil D. Flinkmann +d4d on hackerone d912e3 on github Da-Yoon Chung daboul on github Dag Ekengren Dagobert Michelsen +Daiki Ueno Dair Grant Dambaev Alexander Damian Dixon Damien Adant Damien Vielpeau +Damien Walsh Dan Becker Dan Cristian Dan Donahue Dan Fandrich Dan Jacobson Dan Johnson +Dan Kenigsberg Dan Locks Dan McNulty Dan Nelson @@ -414,6 +510,7 @@ Dan Zitter Daniel at touchtunes Daniel Bankhead Daniel Black +Daniel Carpenter Daniel Cater Daniel Egger Daniel Gustafsson @@ -422,6 +519,7 @@ Daniel Jeliński Daniel Johnson Daniel Kahn Gillmor Daniel Krügler +Daniel Kurečka Daniel Lee Hwang Daniel Lublin Daniel Marjamäki @@ -435,6 +533,8 @@ Daniel Silverstone Daniel Steinberg Daniel Stenberg Daniel Theron +Daniel Valenzuela +Daniel Woelfel Daphne Luong Dario Nieuwenhuis Dario Weißer @@ -454,12 +554,18 @@ David Bau David Benjamin David Binderman David Blaikie +David Bohman David Byron David Cohen +David Cook +David Demelier David E. Narváez +David Earl David Eriksson David Garske +David Goerger David Houlder +David Hu David Hull David J Meyer David James @@ -486,12 +592,19 @@ David Walser David Woodhouse David Wright David Yan +Davide Cassioli +davidedec on github dbrowndan on github +dEajL3kA on github Dengminwen +Denis Baručić Denis Chaplygin Denis Feklushkin +Denis Goleshchikhin +Denis Laxalde Denis Ollier Dennis Clarke +Dennis Felsing Derek Higgins Desmond O. Chang destman on github @@ -500,6 +613,7 @@ Dheeraj Sangamkar Didier Brisebourg Diego Bes Diego Casorran +Dietmar Hauser Dilyan Palauzov Dima Barsky Dima Pasechnik @@ -513,6 +627,10 @@ Dinar Dirk Eddelbuettel Dirk Feytons Dirk Manske +Dirk Wetter +Dirkjan Bussink +Diven Qi +divinity76 on github dkjjr89 on github dkwolfe4 on github Dmitri Shubin @@ -522,12 +640,14 @@ dmitrmax on github Dmitry Bartsevich Dmitry Eremin-Solenikov Dmitry Falko +Dmitry Karpov Dmitry Kostjuchenko Dmitry Kurochkin Dmitry Mikhirev Dmitry Popov Dmitry Rechkin Dmitry S. Baikov +Dmitry Wagin dnivras on github Dolbneff A.V Domenico Andreoli @@ -544,6 +664,7 @@ Douglas E. Wegscheid Douglas Kilpatrick Douglas Mencken Douglas R. Horner +Douglas R. Reno Douglas Steinwand Dov Murik dpull on github @@ -551,6 +672,7 @@ Drake Arconis dtmsecurity on github Duane Cathey Duncan Mac-Vicar Prett +Duncan Wilcox Dustin Boswell Dusty Mabe Duy Phan Thanh @@ -561,8 +683,11 @@ Dániel Bakai Early Ehlinger Earnestly on github Eason-Yu on github +Ebe Janchivdorj +ebejan on github Ebenezer Ikonne Ed Morley +Eddie Lumpkin Edgaras Janušauskas Edin Kadribasic Edmond Yu @@ -574,6 +699,7 @@ Edward Thomson Eelco Dolstra Eetu Ojanen Egon Eckert +Ehren Bendler Eldar Zaitov elelel on github elephoenix on github @@ -583,7 +709,9 @@ Elliot Saba Ellis Pritchard Elmira A Semenova elsamuko on github +emanruse on github Emanuele Bovisio +Emanuele Torre Emil Engler Emil Lerner Emil Romanus @@ -601,11 +729,13 @@ Eric Lavigne Eric Lubin Eric Melville Eric Mertens +Eric Musser Eric Rautman Eric Rescorla Eric Ridge Eric Rosenquist Eric S. Raymond +Eric Sauvageau Eric Thelin Eric Vergnaud Eric Wong @@ -616,28 +746,36 @@ Erik Jacobsen Erik Janssen Erik Johansson Erik Minekus +Erik Olsson +Erik Stenlund Ernest Beinrohr Ernst Sjöstrand Erwan Legrand Erwin Authried +Estanislau Augé-Pujadas Ethan Glasser Camp Etienne Simard Eugene Kotlyarov Evan Jordan +Evangelos Foutras Even Rouault Evert Pot Evgeny Grin Evgeny Turnaev eXeC64 on github Eygene Ryabinkin +Eylem Ugurel Fabian Frank Fabian Hiernaux Fabian Keil Fabian Ruff +Fabian Yamaguchi Fabrice Fontaine Fabrizio Ammollo Fahim Chandurwala Faizur Rahman +Farzin on github +Fawad Mirza fds242 on github Federico Bianchi Fedor Karpelevitch @@ -650,13 +788,21 @@ Felix von Leitner Felix Yan Feng Tu Fernando Muñoz +Filip Lundgren +Filip Salomonsson +Firefox OS +Flameborn on github Flavio Medeiros +Florian Kohnhäuser Florian Pritz Florian Schoppmann +Florian Van Heghe Florian Weimer Florin Petriuc Forrest Cahoon Francisco Moraes +Francisco Munoz +Francisco Olarte Francisco Sedano Francois Petitjean Francois Rivard @@ -670,25 +816,38 @@ Frank Ticheler Frank Van Uffelen František Kučera François Charlier +François Rigault Fred Machado Fred New Fred Noz Fred Stluka Frederic Lepied Frederik B +Frederik Wedel-Heinen Fredrik Thulin +FuccDucc on github +fullincome on github Gabriel Kuri +Gabriel Simmer Gabriel Sjoberg +Gambit Communications +Ganesh Kamath +gaoxingwang on github Garrett Holmstrom +Garrett Squire Gary Maxwell Gaurav Malhotra Gautam Kachroo Gautam Mani +Gavin Wong Gavrie Philipson Gaz Iqbal Gaël Portay +gclinch on github +Gealber Morales Geeknik Labs Geoff Beier +Georeth Zhou Georg Horn Georg Huettenegger Georg Lippitsch @@ -698,6 +857,7 @@ Gerd v. Egidy Gergely Nagy Gerhard Herre Gerrit Bruchhäuser +Gerrit Renker Ghennadi Procopciuc Giancarlo Formicuccia Giaslas Georgios @@ -708,14 +868,19 @@ Gilles Blanc Gilles Vollant Giorgos Oikonomou Gisle Vanem +git-bruh on github GitYuanQu on github Giuseppe Attardi Giuseppe D'Ambrosio Giuseppe Persico +Gleb Ivanovsky Glen A Johnson Jr. Glen Nakamura Glen Scott +Glenn de boer Glenn Sheridan +Glenn Strauss +Godwin Stewart Google Inc. Gordon Marler Gorilla Maguila @@ -728,6 +893,9 @@ Greg Onufer Greg Pratt Greg Rowe Greg Zavertnik +Gregor Jasny +Gregory Jefferis +Gregory Muchka Gregory Nicholls Gregory Szorc Griffin Downs @@ -744,6 +912,8 @@ GwanYeong Kim Gwenole Beauchesne Gökhan Şengün Götz Babin-Ebell +h1zzz on github +H3RSKO on github Hagai Auro Haibo Huang Hamish Mackenzie @@ -756,13 +926,17 @@ Hannes Magnusson Hanno Böck Hanno Kranzhoff Hans Steegers +Hans-Christian Noren Egtvedt Hans-Jurgen May +Hao Wu Hardeep Singh Haris Okanovic Harold Stuart +Harry Sarson Harry Sintonen Harshal Pradhan Hauke Duden +Hayden Roche He Qin Heikki Korpela Heinrich Ko @@ -773,25 +947,37 @@ Helwing Lutz Hendrik Visage Henri Gomez Henrik Gaßmann +Henrik Holst Henrik Storner Henry Ludemann Henry Roeland Herve Amblard +HexTheDragon Hidemoto Nakada +Himanshu Gupta Ho-chi Chen Hoi-Ho Chan Hongli Lai +Hongyi Zhao Howard Blaise Howard Chu hsiao yi +htasta on github Hubert Kario +Hugh Macdonald +Hugo van Kemenade Huzaifa Sidhpurwala +huzunhao on github +hydra3333 on github Hzhijun +iammrtau on github +Ian Blanes Ian D Allen Ian Fette Ian Ford Ian Gulliver Ian Lynagh +Ian Spence Ian Turner Ian Wilkes Ignacio Vazquez-Abrams @@ -801,9 +987,13 @@ Igor Makarov Igor Novoseltsev Igor Polyakov Ihor Karpenko +ihsinme on github Iida Yosiaki +Ikko Ashimine Ilguiz Latypov Ilja van Sprundel +Illarion Taev +illusory-dream on github Ilya Kosarev imilli on github Immanuel Gregoire @@ -812,6 +1002,8 @@ infinnovation-dev on github Ingmar Runge Ingo Ralf Blum Ingo Wilken +Inho Oh +Ionuț-Francisc Oancea Irfan Adilovic Ironbars13 on github Irving Wolfe @@ -823,10 +1015,13 @@ Ivan Avdeev IvanoG on github Ivo Bellin Salarin iz8mbw on github +J. Bromley +Jack Boos Yu Jack Zhang Jackarain on github Jacky Lam Jacob Barthelmeh +Jacob Hoffman-Andrews Jacob Meuser Jacob Moshenko Jactry Zeng @@ -847,6 +1042,7 @@ James Gallagher James Griffiths James Housley James Knight +James Le Cuirot James MacMillan James Slaughter Jamie Lokier @@ -857,9 +1053,13 @@ Jan Chren Jan Ehrhardt Jan Koen Annot Jan Kunder +Jan Mazur Jan Schaumann Jan Schmidt Jan Van Boghout +Jan Venekamp +Jan Verbeek +Jan-Piet Mens JanB on github Janne Johansson Jared Jennings @@ -877,8 +1077,10 @@ Jason S. Priebe Javier Barroso Javier Blazquez Javier G. Sogo +Javier Navarro Javier Sixto Jay Austin +Jay Dommaschk Jayesh A Shah Jaz Fresh Jean Fabrice @@ -891,28 +1093,37 @@ Jean-Louis Lemaire Jean-Marc Ranger Jean-Noël Rouvignac Jean-Philippe Barrette-LaPierre +Jean-Philippe Menil Jeff Connelly Jeff Hodges Jeff Johnson Jeff King Jeff Lawson +Jeff Luszcz Jeff Mears Jeff Phillips Jeff Pohlmeyer Jeff Weber +Jeffrey Tolar Jeffrey Walton +jeffrson on github +Jenny Heino Jens Finkhaeuser Jens Rantil Jens Schleusener Jeremie Rapin +Jeremy Falcon Jeremy Friesner Jeremy Huddleston Jeremy Lainé Jeremy Lin +Jeremy Maitin-Shepard Jeremy Pearson Jeremy Tan +Jeremy Thibault Jeroen Koekkoek Jeroen Ooms +Jerome Mao Jerome Muffat-Meridol Jerome Robert Jerome Vouillon @@ -924,7 +1135,9 @@ Jesse Chisholm Jesse Noller Jesse Tan jethrogb on github +jhoyla on github Jie He +Jim Beveridge Jim Drash Jim Freeman Jim Fuller @@ -934,22 +1147,30 @@ Jimmy Gaussen Jiri Dvorak Jiri Hruska Jiri Jaburek +Jishan Shaikh Jiří Malák +jmdavitt on github jnbr on github Jocelyn Jaubert +Jochem Broekhoff Joe Halpin Joe Malicki Joe Mason Joel Chen Joel Depooter +Joel Jakobsson +Joel Teichroeb +joey-l-us on github Jofell Gallardo Johan Anderson Johan Lantz Johan Nilsson Johan van Selst +Johann150 on github Johannes Bauer Johannes Ernst Johannes G. Kristinsson +Johannes Lesr Johannes Schindelin John A. Bristor John Bradshaw @@ -962,6 +1183,7 @@ John Dennis John Dunn John E. Malmberg John Gardiner Myers +John H. Ayad John Hascall John Janssen John Joseph Bachir @@ -975,6 +1197,7 @@ John Marshall John McGowan John P. McCaskey John Schroeder +John Simpson John Starks John Suprock John V. Chow @@ -986,6 +1209,7 @@ Johnny Luong Jojojov on github Jon DeVree Jon Grubbs +Jon Johnson Jr Jon Nelson Jon Rumsey Jon Sargeant @@ -994,6 +1218,7 @@ Jon Spencer Jon Torrey Jon Travis Jon Turner +Jon Wilkes Jonas Forsman Jonas Minnberg Jonas Schnelli @@ -1004,20 +1229,27 @@ Jonathan Cardoso Machado Jonathan Hseu Jonathan Moerman Jonathan Nieder +Jonathan Watt +Jonathan Wernberg Jongki Suwandi -jonrumsey on github +jonny112 on github Joombalaya on github Joonas Kuorilehto +Jordan Brown Jose Alf Jose Kahan Josef Wolf +Joseph Chen Josh Bialkowski Josh Kapell +Josh Soref joshhe on github Joshua Kwan Joshua Swink Josie Huddleston +Josip Medved Josue Andrade Gomes +José Joaquín Atria Jozef Kralik Juan Barreto Juan F. Codagnone @@ -1027,6 +1259,7 @@ Judson Bishop Juergen Hoetzel Juergen Wilke Jukka Pihl +Julian Montes Julian Noble Julian Ospald Julian Romero Nieto @@ -1035,10 +1268,13 @@ Julian Z Julien Chaffraix Julien Nabet Julien Royer +Jun Tseng Jun-ichiro itojun Hagino +Jun-ya Kato jungle-boogie on github Junho Choi Jurij Smakov +jurisuk on github Juro Bystricky Justin Clift Justin Ehlert @@ -1051,16 +1287,22 @@ János Fekete Jérémy Rocher Jörg Mueller-Tolk Jörn Hartroth +Jürgen Gmach K. R. Walker ka7 on github +Kael1117 on github Kai Engert Kai Noda Kai Sommerfeld Kai-Uwe Rommel Kalle Vahlman Kamil Dudka +Kane York Kang Lin Kang-Jin Lee +Kantanat Wannapaka +Kari Pahula +Karl Chen Karl Moerder Karol Pietrzak Kartik Mahajan @@ -1073,12 +1315,17 @@ Kees Dekker Keith MacDonald Keith McGuigan Keith Mok +Ken Brown Ken Hirsch Ken Rastatter +Kenneth Davidson Kenny To Kent Boortz +Kerem Kat Keshav Krity +Kevin Adler Kevin Baughman +Kevin Burke Kevin Fisk Kevin Ji Kevin Lussier @@ -1086,20 +1333,27 @@ Kevin R. Bulgrien Kevin Reed Kevin Roth Kevin Smith +Kevin Ushey Kim Minjoong Kim Rinnewitz Kim Vandry Kimmo Kinnunen +Kirill Efimov Kirill Marchuk Kjell Ericson Kjetil Jacobsen +Klaus Crusius Klaus Stein Klevtsov Vadim Kobi Gurkan Koen Dergent +Koichi Shiraishi +kokke on github Konstantin Isakov Konstantin Kushnir +kotoriのねこ kouzhudong on github +Kovalkov Dmitrii kreshano on github Kris Kennaway Krishnendu Majumdar @@ -1109,8 +1363,11 @@ Kristian Köhntopp Kristian Mide Kristiyan Tsaklev Kristoffer Gleditsch +Kunal Chandarana Kunal Ekawde Kurt Fankhauser +Kushal Das +Kwon-Young Choi Kyle Abramowitz Kyle Edwards Kyle J. McKay @@ -1122,6 +1379,7 @@ l00p3r on Hackerone Lachlan O'Dea Ladar Levison Lance Ware +Laramie Leavitt Larry Campbell Larry Fahnoe Larry Lin @@ -1134,11 +1392,15 @@ Lars Johannesen Lars Nilsson Lars Torben Wilson Laurent Bonnans +Laurent Dufresne Laurent Rabret Lauri Kasanen Laurie Clark-Michalek +Lawrence Gripper Lawrence Matthews Lawrence Wagerfield +Leah Neukirchen +Leandro Coutinho Legoff Vincent Lehel Bernadt Leif W @@ -1153,9 +1415,14 @@ Leon Breedt Leon Winter Leonardo Rosati Leonardo Taccari +Leszek Kubik +Li Xinwei Liam Healy +Liam Warfield +LigH-de on github lijian996 on github Lijo Antony +lilongyan-huawei on github Linas Vepstas Lindley French Ling Thio @@ -1167,8 +1434,10 @@ Lior Kaplan Lisa Xu Liviu Chircu Liza Alenchery +lllaffer on github Lloyd Fournier Lluís Batlle i Rossell +locpyl-tidnyd on github Loganaden Velvindron Loic Dachary Loren Kirkby @@ -1176,8 +1445,12 @@ Luan Cestari Luca Altea Luca Boccassi Lucas Adamski +Lucas Clemente Vella +Lucas Holt Lucas Pardue +Lucas Servén Marín Lucas Severo +Lucien Zürcher Ludek Finstrle Ludovico Cavedon Ludwig Nussel @@ -1187,12 +1460,15 @@ lukaszgn on github Luke Amery Luke Call Luke Dashjr +Luke Granger-Brown +luminixinc on github Luo Jinghua Luong Dinh Dung Luz Paz Luật Nguyễn Lyman Epp Lyndon Hill +M.R.T on github Maciej Karpiuk Maciej Puzio Maciej W. Rozycki @@ -1201,12 +1477,13 @@ Mahmoud Samir Fayed Maks Naumov Maksim Kuzevanov Maksim Stsepanenka +Malik Idrees Hasan Khan Mamoru Tasaka Mamta Upadhyay Mandy Wu Manfred Schwarb -MAntoniak on github Manuel Massing +Manuj Bhatia Marc Aldorasi Marc Boucher Marc Deslauriers @@ -1239,6 +1516,7 @@ Mario Schroeder Mark Brand Mark Butler Mark Davies +Mark Dodgson Mark Hamilton Mark Incley Mark Karpeles @@ -1246,6 +1524,7 @@ Mark Lentczner Mark Nottingham Mark Salisbury Mark Snelling +Mark Swaanenburg Mark Tully Mark W. Eichin Mark Wotton @@ -1254,19 +1533,24 @@ Markus Elfring Markus Koetter Markus Moeller Markus Oberhumer +Markus Olsson Markus Westerlind Maros Priputen Marquis de Muesli Martijn Koster Martin Ankerl +Martin Bašti Martin C. Martin +Martin Dorey Martin Drasar Martin Dreher Martin Frodl Martin Galvan Martin Gartner Martin Hager +Martin Halle Martin Hedenfalk +Martin Howarth Martin Jansen Martin Kammerhofer Martin Kepplinger @@ -1274,24 +1558,31 @@ Martin Lemke Martin Skinner Martin Staael Martin Storsjö +Martin V Martin Vejnár Marty Kuhrt Maruko +Masaya Suzuki masbug on github Massimiliano Fantuzzi Massimiliano Ziccardi Massimo Callegari Mateusz Loskot Mathias Axelsson +Mathias Gumz Mathieu Legare +Matias N. Goldberg Mats Lidell +Mats Lindestam Matt Arsenault Matt Ford +Matt Holt Matt Kraai Matt McClure Matt Veenstra Matt Witherspoon Matt Wixson +Matteo Baccan Matteo Bignotti Matteo Bignottignotti Matteo Rocco @@ -1301,6 +1592,8 @@ Matthew Hall Matthew Kerwin Matthew Whitehead Matthias Bolte +Matthias Gatto +Matthias Naegler Mattias Fornander Matus Uzak Maurice Barnum @@ -1310,7 +1603,9 @@ Max Dymond Max Katsev Max Kellermann Max Khon +Max Peal Max Savenkov +Max Zettlmeißl Maxim Ivanov Maxim Perenesenko Maxim Prohorov @@ -1318,14 +1613,20 @@ Maxime Larocque Maxime Legros mbeifuss on github mccormickt12 on github +Median Median Stride +mehatzri on github Mehmet Bozkurt Mekonikum Melissa Mears +Melroy van den Berg Mert Yazıcıoğlu Mettgut Jamalla +Michael Afanasiev Michael Anti +Michael Baentsch Michael Benedict Michael Brehm +Michael Brown Michael Calmer Michael Cronenworth Michael Curtis @@ -1334,17 +1635,22 @@ Michael Felt Michael Forney Michael Gmelin Michael Goffioul +Michael Hordijk Michael Jahn Michael Jerris Michael Kalinin Michael Kaufmann Michael Kilburn +Michael Kolechkin Michael Kujawa Michael König Michael Lee Michael Maltese Michael Mealling Michael Mueller +Michael Musset +Michael O'Farrell +Michael Olbrich Michael Osipov Michael Schmid Michael Smith @@ -1355,6 +1661,7 @@ Michael Vittiglio Michael Wallner Michal Bonino Michal Marek +Michal Rus Michal Trybus Michal Čaplygin Michał Antoniak @@ -1377,6 +1684,7 @@ Mike Crowe Mike Dobbs Mike Dowell Mike Frysinger +Mike Gelfand Mike Giancola Mike Hasselberg Mike Henshaw @@ -1386,24 +1694,34 @@ Mike Norton Mike Power Mike Protts Mike Revi +Mike Tzou Miklos Nemeth Miloš Ljumović Mingliang Zhu +Mingtao Yang Miroslav Franc Miroslav Spousta Mischa Salle Mitz Wark mkzero on github +modbw on github Mohamed Lrhazi +Mohamed Osama Mohammad AlSaleh Mohammad Hasbini +Mohammed Naser Mohun Biswas momala454 on github +Momoka Yamamoto moohoorama on github +Morten Minde Neergaard Mostyn Bramley-Moore Moti Avrahami MrdUkk on github MrSorcus on github +Muhammad Herdiansyah +Muhammed Yavuz Nuzumlalı +Murugan Balraj Muz Dima Myk Taylor Nach M. S. @@ -1414,9 +1732,11 @@ Nathan Coulter Nathan O'Sullivan Nathanael Nerode Nathaniel J. Smith +Nathaniel R. Lewis Nathaniel Waisbrot Naveen Chandran Naveen Noel +Neal McBurnett Neal Poole nedres on github neex on github @@ -1426,12 +1746,16 @@ Neil Bowers Neil Dunbar Neil Kolban Neil Spring +neutric on github nevv on HackerOne/curl Niall O'Reilly niallor on github +nian6324 on github nianxuejie on github Nic Roets Nicholas Maniscalco +Nick Banks +Nick Coghlan Nick Draffen Nick Gimbrone Nick Humfrey @@ -1446,6 +1770,8 @@ Nicolas François Nicolas Grekas Nicolas Guillier Nicolas Morey-Chaisemartin +Nicolas Sterchele +Niels Martignène Niels van Tongeren Nikita Schmidt Nikitinskit Dmitriy @@ -1454,25 +1780,32 @@ Niklas Hambüchen Nikolai Kondrashov Nikos Mavrogiannopoulos Nikos Tsipinakis +nimaje on github niner on github Ning Dong Nir Soffer +Niranjan Hasabnis Nis Jorgensen nk +Noam Moshe +NobodyXu on github Nobuhiro Ban Nodak Sodak nopjmp on github Norbert Frese Norbert Kett Norbert Novotny +nosajsnikta on github NTMan on Github Octavio Schroeder Ofer Okhin Vasilij Ola Mork Olaf Flebbe +Olaf Hering Olaf Stüben Oleg Pudeyev +Oleguer Llopart Olen Andoni olesteban on github Oli Kingshott @@ -1480,6 +1813,7 @@ Oliver Gondža Oliver Graute Oliver Kuckertz Oliver Schindler +Oliver Urbann Olivier Berger Olivier Brunel Omar Ramadan @@ -1489,6 +1823,7 @@ Oren Souroujon Oren Tirosh Orgad Shaneh Ori Avtalion +orycho on github osabc on github Oscar Koeroo Oscar Norlander @@ -1500,6 +1835,7 @@ Palo Markovic Paolo Mossino Paolo Piacentini Paras Sethia +parazyd on github Pascal Gaudette Pascal Terjan Pasha Kuznetsov @@ -1528,6 +1864,7 @@ Paul Harrington Paul Harris Paul Hoffman Paul Howarth +Paul Johnson Paul Joyce Paul Marks Paul Marquis @@ -1536,6 +1873,7 @@ Paul Nolan Paul Oliver Paul Querna Paul Saab +Paul Vixie Paulo Roberto Tomasi Pavel Cenek Pavel Gushchin @@ -1548,13 +1886,18 @@ Pavel Volgarev Pavol Markovic Pawel A. Gajda Pawel Kierski +Paweł Kowalski +Paweł Wegner Pedro Larroy Pedro Monreal Pedro Neves pendrek at hackerone Peng Li +Peng-Yu Chen +Per Jensen Per Lundberg Per Malmberg +Per Nilsson Pete Lomax Peter Bray Peter Forret @@ -1563,6 +1906,7 @@ Peter Gal Peter Heuchert Peter Hjalmarsson Peter Korsgaard +Peter Körner Peter Lamare Peter Lamberg Peter Laser @@ -1587,13 +1931,16 @@ Petr Pisar Petr Voytsik Phil Blundell Phil Crump +Phil E. Taylor Phil Karn Phil Lisiecki Phil Pellouchoud Philip Craig Philip Gladstone +Philip H Philip Langdale Philip Prindeville +Philipp Klaus Krause Philipp Waehnert Philippe Hameau Philippe Marguinaud @@ -1603,30 +1950,40 @@ Pierre Pierre Brico Pierre Chapuis Pierre Joye +Pierre Yager Pierre Ynard Pierre-Yves Bigourdan Piotr Dobrogost Piotr Komborski Po-Chuan Hsieh +Pontus Lundkvist Pooyan McSporran Poul T Lomholt Pramod Sharma Prash Dush Praveen Pvs +Prithvi MK Priyanka Shah Przemysław Tomaszewski pszemus on github +puckipedia on github Puneet Pawaia +qiandu2006 on github Quagmire Quanah Gibson-Mount +Quentin Balland Quinn Slack +r-a-sattarov on github R. Dennis Steed +Radek Zajic +Radoslav Georgiev Radu Simionescu Rafa Muyo Rafael Antonio Rafael Sagula Rafayel Mkrtchyan Rafaël Carré +Rafał Mikrut Rainer Canavan Rainer Jung Rainer Koenig @@ -1635,21 +1992,29 @@ Rajesh Naganathan Rajkumar Mandal Ralf S. Engelschall Ralph Beckmann +Ralph Langendam Ralph Mitchell Ram Krushna Mishra +ramsay-jones on github Ran Mozes Randall S. Becker +Randolf J Randy Armstrong Randy McMurchy Raphael Gozzo +Rasmus Melchior Jacobsen +Raul Onitza-Klugman Ravi Pratap Ray Dassen Ray Pekowski Ray Satiro Razvan Cojocaru +rcombs on github +Red Hat Product Security Reed Loden Reinhard Max Reinout van Schouwen +RekGRpth on github Remco van Hooff Remi Gacogne Remo E @@ -1663,12 +2028,16 @@ Rene Bernhardt Rene Rebe Reuven Wachtfogel Reza Arbab +Rianov Viacheslav Ricardo Cadime Ricardo Gomes +Ricardo Martins Rich Burridge +Rich FitzJohn Rich Gray Rich Mirch Rich Rauenzahn +Rich Salz Rich Turner Richard Adams Richard Alcock @@ -1682,14 +2051,18 @@ Richard Gorton Richard Gray Richard Hosking Richard Hsu +Richard Marion Richard Michael Richard Moore Richard Prescott Richard Silverman Richard van den Berg +Richard Whitehouse Richy Kim +Rici Lake Rick Deist Rick Jones +Rick Lane Rick Richardson Rick Welykochy Rickard Hallerbäck @@ -1697,7 +2070,10 @@ Ricki Hirner Ricky Leverence Ricky-Tigg on github Rider Linden +RiderALT on github Rikard Falkeborn +rl1987 on github +Rob Boeckermann Rob Cotrone Rob Crittenden Rob Davies @@ -1707,6 +2083,8 @@ Rob Stanzel Rob Ward Robert A. Monat Robert B. Harris +Robert Brose +Robert Charles Muir Robert D. Young Robert Dunaj Robert Foreman @@ -1715,10 +2093,13 @@ Robert Kolcun Robert Linden Robert Olson Robert Prag +Robert Ronto Robert Schumann Robert Weaver Robert Wruck +Robin A. Meade Robin Cornelius +Robin Douine Robin Johnson Robin Kay Robson Braga Araujo @@ -1728,6 +2109,8 @@ Rodney Simmons Rodric Glaser Rodrigo Silva Roger Leigh +Roger Orr +Roger Young Roland Blom Roland Hieber Roland Krikava @@ -1737,6 +2120,7 @@ Rolland Dudemaine Romain Coltel Romain Fliedel Romain Geissler +romamik om github Roman Koifman Roman Mamedov Romulo A. Ceccon @@ -1745,43 +2129,60 @@ Ron Parker Ron Zapp Ronnie Mose Rosimildo da Silva +Ross Burton Roy Bellingan +Roy Li Roy Shan +Rui LIU +Rui Pinheiro Rune Kleveland Ruslan Baratov Ruslan Gazizov Rutger Hofman Ruurd Beerstra RuurdBeerstra on github +Ryan Beck-Buysse Ryan Braud Ryan Chan +Ryan Mast Ryan Nelson Ryan Schmidt Ryan Scott +Ryan Sleevi Ryan Winograd +ryancaicse on github Ryuichi KAWAMATA Rémy Léone S. Moonesamy +Sai Ram Kunala Salah-Eddin Shaban +Saleem Abdulrasool Salvador Dávila Salvatore Sorrentino Sam Deane Sam Hurst Sam Roth Sam Schanken +Samanta Navarro Sampo Kellomaki Samuel Díaz García +Samuel Henrique Samuel Listopad +Samuel Marks Samuel Surtees Samuel Thibault +Samuel Tranchet Sander Gates Sandor Feldi +Sandro Jaeckel Santhana Todatry Santino Keupp Saqib Ali Sara Golemon Saran Neti Sascha Swiercy +Sascha Zengler +Satadru Pramanik Saul good Saurav Babu sayrer on github @@ -1794,15 +2195,19 @@ Scott McCreary Sean Boudreau Sean Burford Sean MacLennan +Sean McArthur Sean Miller +Sean Molenaar Sebastiaan van Erk Sebastian Haglund Sebastian Mundry Sebastian Pohlschmidt Sebastian Rasmussen +Sebastian Sterk Senthil Raja Velu Sergei Kuzmin Sergei Nikulov +Sergey Markelov Sergey Ogryzkov Sergey Tatarincev Sergii Kavunenko @@ -1810,6 +2215,8 @@ Sergii Pylypenko Sergio Ballestrero Sergio Barresi Sergio Borghese +Sergio Durigan Junior +sergio-nsk on github Serj Kalichev Seshubabu Pasam Seth Mos @@ -1821,25 +2228,33 @@ Shankar Jadhavar Shao Shuchao Sharad Gupta Shard +Sharon Brizinov Shaun Jackman Shawn Landden Shawn Poulson +Shikha Sharma Shine Fan Shiraz Kanga +shithappens2016 on github Shlomi Fish Shmulik Regev Siddhartha Prakash Jain +siddharthchhabrap on github Sidney San Martín Siegfried Gyuricsko silveja1 on github +Simon Chalifoux Simon Dick Simon H. Simon Josefsson Simon Legner Simon Liu Simon Warta +Siva Sivaraman SLDiggie on github smuellerDD on github +sn on hackerone +sofaboss on github Somnath Kundu Song Ma Sonia Subramanian @@ -1848,34 +2263,46 @@ Spezifant on github Spiridonoff A.V Spoon Man Spork Schivago +sspiri on github sstruchtrup on github Stadler Stephan +Stan Hu Stan van de Burgt Stanislav Ivochkin Stanislav Zidek +Stathis Kapnidis +Stav Nir steelman on github Stefan Agner Stefan Bühler Stefan Eissing Stefan Esser Stefan Grether +Stefan Huber Stefan Kanthak +Stefan Karpinski Stefan Krause Stefan Neis +Stefan Strogin Stefan Teleman Stefan Tomanek Stefan Ulrich +Stefan Yohansson Stefano Simonelli Steinar H. Gunderson steini2000 on github Stepan Broz +Stepan Efremov Stephan Bergmann Stephan Lagerholm Stephan Mühlstrasser Stephan Szabo +Stephane Pellegrino +Stephen Boost Stephen Brokenshire Stephen Collyer Stephen Kick +Stephen M. Coakley Stephen More Stephen Toub Sterling Hughes @@ -1894,6 +2321,8 @@ Steven G. Johnson Steven Gu Steven M. Schweda Steven Parkes +Steven Penny +Stewart Gebbie Stian Soiland-Reyes Stoned Elipot stootill on github @@ -1908,33 +2337,43 @@ Sven Neuhaus Sven Wegener Svyatoslav Mishyn swalkaus at yahoo.com +sylgal on github Sylvestre Ledru Symeon Paraschoudis Sébastien Willemijns T. Bharath T. Yamada +T200proX7 on github +Tadej Vengust Tae Hyoung Ahn -Tae Wong Taiyu Len Taneli Vähäkangas Tanguy Fautre +Taras Kushnir tarek112 on github Tatsuhiro Tsujikawa +tawmoto on github +tbugfinder on github Teemu Yli-Elsila Temprimus Terri Oda Terry Wu +thanhchungbtc on github The Infinnovation team TheAssassin on github Theodore Dubois +therealhirudo on github tholin on github +Thomas Bouzerar Thomas Braun +Thomas Danielsson Thomas Gamper Thomas Glanzmann Thomas J. Moore Thomas Klausner Thomas L. Shinnick Thomas Lopatic +Thomas M. DuBuisson Thomas Petazzoni Thomas Ruecker Thomas Schwinge @@ -1954,22 +2393,32 @@ Tim Heckman Tim Mcdonough Tim Newsome Tim Rühsen +Tim Sedlmeyer Tim Sneddon Tim Stack Tim Starling Tim Tassonis Tim Verhoeven +Timo Lange Timo Sirainen Timotej Lazar Timothe Litt +Timothy Gu Timothy Polich +Timur Artikov Tinus van den Berg TJ Saunders +Tk Xiong +tlahn on github +tmkk on github Tobias Blomberg +Tobias Gabriel Tobias Hieta Tobias Hintze Tobias Lindgren Tobias Markus +Tobias Nießen +Tobias Nyholm Tobias Rundström Tobias Stoeckmann Toby Peterson @@ -1980,6 +2429,7 @@ Todd Short Todd Vierling Tom Benoist Tom Donovan +Tom G. Christensen Tom Grace Tom Greenslade Tom Lee @@ -1992,6 +2442,7 @@ Tom Sparrow Tom van der Woerdt Tom Wright Tom Zerucha +Tomas Berger Tomas Hoger Tomas Jakobsson Tomas Mlcoch @@ -2003,6 +2454,9 @@ Tomasz Kojm Tomasz Lacki Tommie Gannert tommink[at]post.pl +Tommy Chiang +Tommy Odom +Tommy Petty Tommy Tam Ton Voon Toni Moreno @@ -2022,6 +2476,7 @@ Trivikram Kamat Troels Walsted Hansen Troy Engel Tseng Jun +Tuomas Siipola Tuomo Rinne Tupone Alfredo Tyler Hall @@ -2031,9 +2486,18 @@ Ulf Samuelsson Ulrich Doehner Ulrich Telle Ulrich Zadow +updatede on github +UrsusArctos on github +User Sg +ustcqidi on github +Vadim Grinshpun Valentin David +Valentin Richter +Valentyn Korniienko +Valentín Gutiérrez Valerii Zapodovnikov vanillajonathan on github +Varnavas Papaioannou Vasiliy Faronov Vasily Lobaskin Vasy Okhin @@ -2042,6 +2506,7 @@ Venkataramana Mokkapati Vicente Garcia Victor Magierski Victor Snezhko +Victor Vieux Vijay Panghal Vikram Saxena Viktor Szakats @@ -2050,16 +2515,21 @@ Ville Skyttä Vilmos Nebehaj Vincas Razma Vincent Bronner +Vincent Grande Vincent Le Normand Vincent Penquerc'h Vincent Sanders Vincent Torri vitaha85 on github +Vitaly Varyvdin +vl409 on github Vlad Grachov Vlad Ureche Vladimir Grishchenko Vladimir Kotal Vladimir Lazarenko +Vladimir Panteleev +Vladimir Varlamov Vlastimil Ovčáčík Vojtech Janota Vojtech Minarik @@ -2067,6 +2537,7 @@ Vojtěch Král Volker Schmid Vsevolod Novikov vshmuk on hackerone +Vyron Tsingaras W. Mark Kubacki Waldek Kozba Walter J. Mack @@ -2076,6 +2547,8 @@ Wayne Haigh Wenchao Li Wenxiang Qian Werner Koch +Werner Stolz +Wes Hinsley wesinator on github Wesley Laxton Wesley Miaw @@ -2083,23 +2556,32 @@ Wez Furlong Wham Bang Wilfredo Sanchez Will Dietz +Will Roberts Willem Sparreboom William A. Rowe Jr William Ahern +William Desportes wmsch on github wncboy on github Wojciech Zwiefka Wouter Van Rooy Wu Yongzheng Wyatt O'Day +Wyatt OʼDay +x2018 on github Xavier Bouchoux +XhmikosR on github XhstormR on github Xiang Xiao Xiangbin Li +Xiaoke Wang Xiaoyin Liu XmiliaH on github +xnynx on github +xwxbug on github Yaakov Selkowitz Yang Tse +Yaobin Wen Yarram Sunil Yasuharu Yamada Yasuhiro Matsumoto @@ -2110,30 +2592,47 @@ ygthien on github Yi Huang Yiming Jing Yingwei Liu +Ymir1711 on github Yonggang Luo +Yongkang Huang +Younes El-karama youngchopin on github Yousuke Kimoto Yu Xin Yukihiro Kawada Yun SangHo +Yuri Slobodyanyuk Yuriy Sosov +Yusuke Nakamura Yves Arrouye Yves Lejeune +z2-2z on github +z2_ on hackerone Zachary Seguin Zdenek Pavlas Zekun Ni zelinchen on github Zenju on github Zero King +Zhang Xiuhua Zhao Yisha Zhaoyang Wu Zhibiao Wu Zhouyihai Ding +ZimCodes on github +zloi-user on github Zmey Petroff Zvi Har'El zzq1015 on github +Ádler Jonas Gross +Érico Nogueira İsmail Dönmez Łukasz Domeradzki Štefan Kremeň +Борис Верховский +Коваленко Анатолий Викторович Никита Дорохин +ウさん +不确定 加藤郁之 +梦终无痕 diff --git a/extern/curl/docs/THANKS-filter b/extern/curl/docs/THANKS-filter index cabc939335..ff2de7773b 100644 --- a/extern/curl/docs/THANKS-filter +++ b/extern/curl/docs/THANKS-filter @@ -1,3 +1,25 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### +# # This is a list of names we have recorded that already are thanked # appropriately in THANKS. This list contains variations of their names and # their "canonical" name. This file is used for scripting purposes to avoid @@ -99,3 +121,9 @@ s/Ale Vesely/Alessandro Vesely/ s/Yamada Yasuharu/Yasuharu Yamada/ s/Jim Gallagher/James Gallagher/ s/Steve Brokenshire/Stephen Brokenshire/ +s/wangp on github/Peter Wang/ +s# *autobuild https://.*## +s/William A Rowe Jr/William A. Rowe Jr/ +s/jonrumsey on github/Jon Rumsey/ +s/Travis Burtrum on github// +s/i-ky on github/Gleb Ivanovsky/ diff --git a/extern/curl/docs/TODO b/extern/curl/docs/TODO index b288e4dbb4..5c5a77a835 100644 --- a/extern/curl/docs/TODO +++ b/extern/curl/docs/TODO @@ -7,14 +7,14 @@ Things that could be nice to do in the future Things to do in project curl. Please tell us what you think, contribute and - send us patches that improve things! + send us patches that improve things. Be aware that these are things that we could do, or have once been considered things we could do. If you want to work on any of these areas, please consider bringing it up for discussions first on the mailing list so that we - all agree it is still a good idea for the project! + all agree it is still a good idea for the project. - All bugs documented in the KNOWN_BUGS document are subject for fixing! + All bugs documented in the KNOWN_BUGS document are subject for fixing. 1. libcurl 1.1 TFO support on Windows @@ -22,6 +22,7 @@ 1.3 struct lifreq 1.4 alt-svc sharing 1.5 get rid of PATH_MAX + 1.6 native IDN support on macOS 1.7 Support HTTP/2 for HTTP(S) proxies 1.8 CURLOPT_RESOLVE for any port number 1.9 Cache negative name resolves @@ -29,20 +30,21 @@ 1.11 minimize dependencies with dynamically loaded modules 1.12 updated DNS server while running 1.13 c-ares and CURLOPT_OPENSOCKETFUNCTION - 1.14 Typesafe curl_easy_setopt() 1.15 Monitor connections in the connection pool 1.16 Try to URL encode given URL 1.17 Add support for IRIs - 1.18 try next proxy if one doesn't work + 1.18 try next proxy if one does not work + 1.19 provide timing info for each redirect 1.20 SRV and URI DNS records + 1.21 netrc caching and sharing 1.22 CURLINFO_PAUSE_STATE 1.23 Offer API to flush the connection pool - 1.24 TCP Fast Open for windows 1.25 Expose tried IP addresses that failed - 1.27 hardcode the "localhost" addresses 1.28 FD_CLOEXEC 1.29 Upgrade to websockets 1.30 config file parsing + 1.31 erase secrets from heap/stack after use + 1.32 add asynch getaddrinfo support 2. libcurl - multi interface 2.1 More non-blocking @@ -51,31 +53,38 @@ 2.4 Split connect and authentication process 2.5 Edge-triggered sockets should work 2.6 multi upkeep + 2.7 Virtual external sockets + 2.8 dynamically decide to use socketpair 3. Documentation + 3.1 Improve documentation about fork safety 3.2 Provide cmake config-file 4. FTP 4.1 HOST 4.2 Alter passive/active on failure and retry 4.3 Earlier bad letter detection + 4.4 Support CURLOPT_PREQUOTE for dir listings too 4.5 ASCII support 4.6 GSSAPI via Windows SSPI 4.7 STAT for LIST without data connection - 4.8 Option to ignore private IP addresses in PASV response 5. HTTP - 5.1 Better persistency for HTTP 1.0 + 5.2 Set custom client ip when using haproxy protocol 5.3 Rearrange request header order 5.4 Allow SAN names in HTTP/2 server push 5.5 auth= in URLs + 5.6 alt-svc should fallback if alt-svc does not work + 5.7 Require HTTP version X or higher 6. TELNET 6.1 ditch stdin 6.2 ditch telnet-specific select 6.3 feature negotiation debug data + 6.4 exit immediately upon connection if stdin is /dev/null 7. SMTP + 7.1 Passing NOTIFY option to CURLOPT_MAIL_RCPT 7.2 Enhanced capability support 7.3 Add CURLOPT_MAIL_CLIENT option @@ -96,62 +105,76 @@ 11.3 Use NTLMv2 11.4 Create remote directories - 12. New protocols + 12. FILE + 12.1 Directory listing for FILE: - 13. SSL + 13. TLS + 13.1 TLS-PSK with OpenSSL 13.2 Provide mutex locking API - 13.3 Support in-memory certs/ca certs/keys + 13.3 Defeat TLS fingerprinting 13.4 Cache/share OpenSSL contexts 13.5 Export session ids 13.6 Provide callback for cert verification - 13.7 improve configure --with-ssl + 13.7 Less memory massaging with Schannel 13.8 Support DANE + 13.9 TLS record padding 13.10 Support Authority Information Access certificate extension (AIA) 13.11 Support intermediate & root pinning for PINNEDPUBLICKEY - 13.12 Support HSTS + 13.13 Make sure we forbid TLS 1.3 post-handshake authentication 13.14 Support the clienthello extension 14. GnuTLS 14.2 check connection - 15. WinSSL/SChannel - 15.1 Add support for client certificate authentication - 15.3 Add support for the --ciphers option - 15.4 Add option to disable client certificate auto-send + 15. Schannel + 15.1 Extend support for client certificate authentication + 15.2 Extend support for the --ciphers option + 15.4 Add option to allow abrupt server closure 16. SASL 16.1 Other authentication mechanisms 16.2 Add QOP support to GSSAPI authentication - 16.3 Support binary messages (i.e.: non-base64) 17. SSH protocols 17.1 Multiplexing 17.2 Handle growing SFTP files - 17.3 Support better than MD5 hostkey hash + 17.3 Read keys from ~/.ssh/id_ecdsa, id_ed25519 17.4 Support CURLOPT_PREQUOTE + 17.5 SSH over HTTPS proxy with more backends + 17.6 SFTP with SCP:// 18. Command line tool 18.1 sync 18.2 glob posts - 18.3 prevent file overwriting 18.4 --proxycommand 18.5 UTF-8 filenames in Content-Disposition + 18.6 Option to make -Z merge lined based outputs on stdout 18.7 at least N milliseconds between requests + 18.8 Consider convenience options for JSON and XML? 18.9 Choose the name of file in braces for complex URLs 18.10 improve how curl works in a windows console window 18.11 Windows: set attribute 'archive' for completed downloads 18.12 keep running, read instructions from pipe/socket + 18.13 Ratelimit or wait between serial requests + 18.14 --dry-run 18.15 --retry should resume 18.16 send only part of --data 18.17 consider file name from the redirected URL with -O ? 18.18 retry on network is unreachable 18.19 expand ~/ in config files 18.20 host name sections in config files + 18.21 retry on the redirected-to URL + 18.23 Set the modification date on an uploaded file + 18.24 Use multiple parallel transfers for a single download + 18.25 Prevent terminal injection when writing to terminal + 18.26 Custom progress meter update interval 19. Build 19.1 roffit 19.2 Enable PIE and RELRO by default - 19.3 cmake test suite improvements + 19.3 Do not use GNU libtool on OpenBSD + 19.4 Package curl for Windows in a signed installer + 19.5 make configure use --cache-file more and better 20. Test suite 20.1 SSL tunnel @@ -161,21 +184,10 @@ 20.5 Add support for concurrent connections 20.6 Use the RFC6265 test suite 20.7 Support LD_PRELOAD on macOS - 20.8 Run web-platform-tests url tests - - 21. Next SONAME bump - 21.1 http-style HEAD output for FTP - 21.2 combine error codes - 21.3 extend CURLOPT_SOCKOPTFUNCTION prototype - - 22. Next major release - 22.1 cleanup return codes - 22.2 remove obsolete defines - 22.3 size_t - 22.4 remove several functions - 22.5 remove CURLOPT_FAILONERROR - 22.7 remove progress meter from libcurl - 22.8 remove 'curl_httppost' from public + 20.8 Run web-platform-tests URL tests + + 21. MQTT + 21.1 Support rate-limiting ============================================================================== @@ -183,6 +195,10 @@ 1.1 TFO support on Windows + libcurl supports the CURLOPT_TCP_FASTOPEN option since 7.49.0 for Linux and + Mac OS. Windows supports TCP Fast Open starting with Windows 10, version 1607 + and we should add support for it. + TCP Fast Open is supported on several platforms but not on Windows. Work on this was once started but never finished. @@ -190,7 +206,7 @@ 1.2 Consult %APPDATA% also for .netrc - %APPDATA%\.netrc is not considered when running on Windows. Shouldn't it? + %APPDATA%\.netrc is not considered when running on Windows. should not it? See https://github.com/curl/curl/issues/4016 @@ -214,7 +230,17 @@ Currently the libssh2 SSH based code uses it, but to remove PATH_MAX from there we need libssh2 to properly tell us when we pass in a too small buffer - and its current API (as of libssh2 1.2.7) doesn't. + and its current API (as of libssh2 1.2.7) does not. + +1.6 native IDN support on macOS + + On recent macOS versions, the getaddrinfo() function itself has built-in IDN + support. By setting the AI_CANONNAME flag, the function will return the + encoded name in the ai_canonname struct field in the returned information. + This could be used by curl on macOS when built without a separate IDN library + and an IDN host name is used in a URL. + + See initial work in https://github.com/curl/curl/pull/5371 1.7 Support HTTP/2 for HTTP(S) proxies @@ -252,7 +278,7 @@ We can create a system with loadable modules/plug-ins, where these modules would be the ones that link to 3rd party libs. That would allow us to avoid having to load ALL dependencies since only the necessary ones for this - app/invoke/used protocols would be necessary to load. See + app/invoke/used protocols would be necessary to load. See https://github.com/curl/curl/issues/349 1.12 updated DNS server while running @@ -261,7 +287,7 @@ is may cause name resolves to fail unless res_init() is called. We should consider calling res_init() + retry once unconditionally on all name resolve failures to mitigate against this. Firefox works like that. Note that Windows - doesn't have res_init() or an alternative. + does not have res_init() or an alternative. https://github.com/curl/curl/issues/2251 @@ -271,27 +297,10 @@ close them with the CURLOPT_CLOSESOCKETFUNCTION callback. However, c-ares does not use those functions and instead opens and closes the sockets itself. This means that when curl passes the c-ares socket to the - CURLMOPT_SOCKETFUNCTION it isn't owned by the application like other sockets. + CURLMOPT_SOCKETFUNCTION it is not owned by the application like other sockets. See https://github.com/curl/curl/issues/2734 -1.14 Typesafe curl_easy_setopt() - - One of the most common problems in libcurl using applications is the lack of - type checks for curl_easy_setopt() which happens because it accepts varargs - and thus can take any type. - - One possible solution to this is to introduce a few different versions of the - setopt version for the different kinds of data you can set. - - curl_easy_set_num() - sets a long value - - curl_easy_set_large() - sets a curl_off_t value - - curl_easy_set_ptr() - sets a pointer - - curl_easy_set_cb() - sets a callback PLUS its callback data - 1.15 Monitor connections in the connection pool libcurl's connection cache or pool holds a number of open connections for the @@ -301,10 +310,11 @@ reuse purpose it is verified that it is still alive. Those connections may get closed by the server side for idleness or they may - get a HTTP/2 ping from the peer to verify that they're still alive. By adding - monitoring of the connections while in the pool, libcurl can detect dead - connections (and close them) better and earlier, and it can handle HTTP/2 - pings to keep such ones alive even when not actively doing transfers on them. + get an HTTP/2 ping from the peer to verify that they are still alive. By + adding monitoring of the connections while in the pool, libcurl can detect + dead connections (and close them) better and earlier, and it can handle + HTTP/2 pings to keep such ones alive even when not actively doing transfers + on them. 1.16 Try to URL encode given URL @@ -324,7 +334,7 @@ To make that work smoothly for curl users even on Windows, curl would probably need to be able to convert from several input encodings. -1.18 try next proxy if one doesn't work +1.18 try next proxy if one does not work Allow an application to specify a list of proxies to try, and failing to connect to the first go on and try the next instead until the list is @@ -333,10 +343,26 @@ https://github.com/curl/curl/issues/896 +1.19 provide timing info for each redirect + + curl and libcurl provide timing information via a set of different + time-stamps (CURLINFO_*_TIME). When curl is following redirects, those + returned time value are the accumulated sums. An improvement could be to + offer separate timings for each redirect. + + https://github.com/curl/curl/issues/6743 + 1.20 SRV and URI DNS records Offer support for resolving SRV and URI DNS records for libcurl to know which - server to connect to for various protocols (including HTTP!). + server to connect to for various protocols (including HTTP). + +1.21 netrc caching and sharing + + The netrc file is read and parsed each time a connection is setup, which + means that if a transfer needs multiple connections for authentication or + redirects, the file might be reread (and parsed) multiple times. This makes + it impossible to provide the file as a pipe. 1.22 CURLINFO_PAUSE_STATE @@ -349,31 +375,15 @@ An API could allow a forced flush or just a forced loop that would properly close all connections that have been closed by the server already. -1.24 TCP Fast Open for windows - - libcurl supports the CURLOPT_TCP_FASTOPEN option since 7.49.0 for Linux and - Mac OS. Windows supports TCP Fast Open starting with Windows 10, version 1607 - and we should add support for it. - 1.25 Expose tried IP addresses that failed - When libcurl fails to connect to a host, it should be able to offer the - application the list of IP addresses that were used in the attempt. + When libcurl fails to connect to a host, it could offer the application the + addresses that were used in the attempt. Source + dest IP, source + dest port + and protocol (UDP or TCP) for each failure. Possibly as a callback. Perhaps + also provide "reason". https://github.com/curl/curl/issues/2126 -1.27 hardcode the "localhost" addresses - - There's this new spec getting adopted that says "localhost" should always and - unconditionally be a local address and not get resolved by a DNS server. A - fine way for curl to fix this would be to simply hard-code the response to - 127.0.0.1 and/or ::1 (depending on what IP versions that are requested). This - is what the browsers probably will do with this hostname. - - https://bugzilla.mozilla.org/show_bug.cgi?id=1220810 - - https://tools.ietf.org/html/draft-ietf-dnsop-let-localhost-be-localhost-02 - 1.28 FD_CLOEXEC It sets the close-on-exec flag for the file descriptor, which causes the file @@ -388,7 +398,7 @@ See https://github.com/curl/curl/issues/3523 Michael Kaufmann suggestion here: - https://curl.haxx.se/video/curlup-2017/2017-03-19_05_Michael_Kaufmann_Websocket_support_for_curl.mp4 + https://curl.se/video/curlup-2017/2017-03-19_05_Michael_Kaufmann_Websocket_support_for_curl.mp4 1.30 config file parsing @@ -398,18 +408,46 @@ See https://github.com/curl/curl/issues/3698 +1.31 erase secrets from heap/stack after use + + Introducing a concept and system to erase secrets from memory after use, it + could help mitigate and lessen the impact of (future) security problems etc. + However: most secrets are passed to libcurl as clear text from the + application and then clearing them within the library adds nothing... + + https://github.com/curl/curl/issues/7268 + +1.32 add asynch getaddrinfo support + + Use getaddrinfo_a() to provide an asynch name resolver backend to libcurl + that does not use threads and does not depend on c-ares. The getaddrinfo_a + function is (probably?) glibc specific but that is a widely used libc among + our users. + + https://github.com/curl/curl/pull/6746 + 2. libcurl - multi interface 2.1 More non-blocking - Make sure we don't ever loop because of non-blocking sockets returning + Make sure we do not ever loop because of non-blocking sockets returning EWOULDBLOCK or similar. Blocking cases include: - - Name resolves on non-windows unless c-ares or the threaded resolver is used + - Name resolves on non-windows unless c-ares or the threaded resolver is used. + + - The threaded resolver may block on cleanup: + https://github.com/curl/curl/issues/4852 + - file:// transfers + - TELNET transfers + + - GSSAPI authentication for FTP transfers + - The "DONE" operation (post transfer protocol-specific actions) for the - protocols SFTP, SMTP, FTP. Fixing Curl_done() for this is a worthy task. + protocols SFTP, SMTP, FTP. Fixing multi_done() for this is a worthy task. + + - curl_multi_remove_handle for any of the above. See section 2.3. 2.2 Better support for same name resolves @@ -431,7 +469,7 @@ 2.4 Split connect and authentication process The multi interface treats the authentication process as part of the connect - phase. As such any failures during authentication won't trigger the relevant + phase. As such any failures during authentication will not trigger the relevant QUIT or LOGOFF for protocols such as IMAP, POP3 and SMTP. 2.5 Edge-triggered sockets should work @@ -449,8 +487,29 @@ See https://github.com/curl/curl/issues/3199 +2.7 Virtual external sockets + + libcurl performs operations on the given file descriptor that presumes it is + a socket and an application cannot replace them at the moment. Allowing an + application to fully replace those would allow a larger degree of freedom and + flexibility. + + See https://github.com/curl/curl/issues/5835 + +2.8 dynamically decide to use socketpair + + For users who do not use curl_multi_wait() or do not care for + curl_multi_wakeup(), we could introduce a way to make libcurl NOT + create a socketpair in the multi handle. + + See https://github.com/curl/curl/issues/4829 + 3. Documentation +3.1 Improve documentation about fork safety + + See https://github.com/curl/curl/issues/6968 + 3.2 Provide cmake config-file A config-file package is a set of files provided by us to allow applications @@ -464,23 +523,30 @@ HOST is a command for a client to tell which host name to use, to offer FTP servers named-based virtual hosting: - https://tools.ietf.org/html/rfc7151 + https://datatracker.ietf.org/doc/html/rfc7151 4.2 Alter passive/active on failure and retry When trying to connect passively to a server which only supports active connections, libcurl returns CURLE_FTP_WEIRD_PASV_REPLY and closes the connection. There could be a way to fallback to an active connection (and - vice versa). https://curl.haxx.se/bug/feature.cgi?id=1754793 + vice versa). https://curl.se/bug/feature.cgi?id=1754793 4.3 Earlier bad letter detection Make the detection of (bad) %0d and %0a codes in FTP URL parts earlier in the process to avoid doing a resolve and connect in vain. +4.4 Support CURLOPT_PREQUOTE for dir listings too + + The lack of support is mostly an oversight and requires the FTP state machine + to get updated to get fixed. + + https://github.com/curl/curl/issues/8602 + 4.5 ASCII support - FTP ASCII transfers do not follow RFC959. They don't convert the data + FTP ASCII transfers do not follow RFC959. They do not convert the data accordingly. 4.6 GSSAPI via Windows SSPI @@ -497,18 +563,14 @@ This is not detailed in any FTP specification. -4.8 Option to ignore private IP addresses in PASV response - - Some servers respond with and some other FTP client implementations can - ignore private (RFC 1918 style) IP addresses when received in PASV responses. - To consider for libcurl as well. See https://github.com/curl/curl/issues/1455 - 5. HTTP -5.1 Better persistency for HTTP 1.0 +5.2 Set custom client ip when using haproxy protocol + + This would allow testing servers with different client ip addresses (without + using x-forward-for header). - "Better" support for persistent connections over HTTP 1.0 - https://curl.haxx.se/bug/feature.cgi?id=1089001 + https://github.com/curl/curl/issues/5125 5.3 Rearrange request header order @@ -543,6 +605,21 @@ Additionally this should be implemented for proxy base URLs as well. +5.6 alt-svc should fallback if alt-svc does not work + + The alt-svc: header provides a set of alternative services for curl to use + instead of the original. If the first attempted one fails, it should try the + next etc and if all alternatives fail go back to the original. + + See https://github.com/curl/curl/issues/4908 + +5.7 Require HTTP version X or higher + + curl and libcurl provide options for trying higher HTTP versions (for example + HTTP/2) but then still allows the server to pick version 1.1. We could + consider adding a way to require a minimum version. + + See https://github.com/curl/curl/issues/7980 6. TELNET @@ -555,16 +632,31 @@ 6.2 ditch telnet-specific select Move the telnet support's network select() loop go away and merge the code - into the main transfer loop. Until this is done, the multi interface won't + into the main transfer loop. Until this is done, the multi interface will not work for telnet. 6.3 feature negotiation debug data Add telnet feature negotiation data to the debug callback as header data. +6.4 exit immediately upon connection if stdin is /dev/null + + If it did, curl could be used to probe if there's an server there listening + on a specific port. That is, the following command would exit immediately + after the connection is established with exit code 0: + + curl -s --connect-timeout 2 telnet://example.com:80 NOTIFY=SUCCESS,FAILURE" ); + + https://github.com/curl/curl/issues/8232 + 7.2 Enhanced capability support Add the ability, for an application that uses libcurl, to obtain the list of @@ -578,7 +670,7 @@ hack ;-) Please see the following thread for more information: - https://curl.haxx.se/mail/lib-2012-05/0178.html + https://curl.se/mail/lib-2012-05/0178.html 8. POP3 @@ -620,25 +712,42 @@ 11.1 File listing support -Add support for listing the contents of a SMB share. The output should probably -be the same as/similar to FTP. + Add support for listing the contents of a SMB share. The output should + probably be the same as/similar to FTP. 11.2 Honor file timestamps -The timestamp of the transferred file should reflect that of the original file. + The timestamp of the transferred file should reflect that of the original + file. 11.3 Use NTLMv2 -Currently the SMB authentication uses NTLMv1. + Currently the SMB authentication uses NTLMv1. 11.4 Create remote directories -Support for creating remote directories when uploading a file to a directory -that doesn't exist on the server, just like --ftp-create-dirs. + Support for creating remote directories when uploading a file to a directory + that does not exist on the server, just like --ftp-create-dirs. + + +12. FILE + +12.1 Directory listing for FILE: + + Add support for listing the contents of a directory accessed with FILE. The + output should probably be the same as/similar to FTP. + -12. New protocols +13. TLS -13. SSL +13.1 TLS-PSK with OpenSSL + + Transport Layer Security pre-shared key ciphersuites (TLS-PSK) is a set of + cryptographic protocols that provide secure communication based on pre-shared + keys (PSKs). These pre-shared keys are symmetric keys shared in advance among + the communicating parties. + + https://github.com/curl/curl/issues/5081 13.2 Provide mutex locking API @@ -646,20 +755,20 @@ that doesn't exist on the server, just like --ftp-create-dirs. library, so that the same application code can use mutex-locking independently of OpenSSL or GnutTLS being used. -13.3 Support in-memory certs/ca certs/keys +13.3 Defeat TLS fingerprinting + + By changing the order of TLS extensions provided in the TLS handshake, it is + sometimes possible to circumvent TLS fingerprinting by servers. The TLS + extension order is of course not the only way to fingerprint a client. - You can specify the private and public keys for SSH/SSL as file paths. Some - programs want to avoid using files and instead just pass them as in-memory - data blobs. There's probably a challenge to make this work across the - plethory of different TLS and SSH backends that curl supports. - https://github.com/curl/curl/issues/2310 + See https://github.com/curl/curl/issues/8119 13.4 Cache/share OpenSSL contexts "Look at SSL cafile - quick traces look to me like these are done on every request as well, when they should only be necessary once per SSL context (or once per handle)". The major improvement we can rather easily do is to make - sure we don't create and kill a new SSL "context" for every request, but + sure we do not create and kill a new SSL "context" for every request, but instead make one for every connection and re-use that SSL context in the same style connections are re-used. It will make us use slightly more memory but it will libcurl do less creations and deletions of SSL contexts. @@ -681,13 +790,15 @@ that doesn't exist on the server, just like --ftp-create-dirs. 13.6 Provide callback for cert verification OpenSSL supports a callback for customised verification of the peer - certificate, but this doesn't seem to be exposed in the libcurl APIs. Could - it be? There's so much that could be done if it were! + certificate, but this does not seem to be exposed in the libcurl APIs. Could + it be? There's so much that could be done if it were. -13.7 improve configure --with-ssl +13.7 Less memory massaging with Schannel - make the configure --with-ssl option first check for OpenSSL, then GnuTLS, - then NSS... + The Schannel backend does a lot of custom memory management we would rather + avoid: the repeated alloc + free in sends and the custom memory + realloc + system for encrypted and decrypted data. That should be avoided and reduced + for 1) efficiency and 2) safety. 13.8 Support DANE @@ -696,19 +807,27 @@ that doesn't exist on the server, just like --ftp-create-dirs. https://www.rfc-editor.org/rfc/rfc6698.txt An initial patch was posted by Suresh Krishnaswamy on March 7th 2013 - (https://curl.haxx.se/mail/lib-2013-03/0075.html) but it was a too simple + (https://curl.se/mail/lib-2013-03/0075.html) but it was a too simple approach. See Daniel's comments: - https://curl.haxx.se/mail/lib-2013-03/0103.html . libunbound may be the + https://curl.se/mail/lib-2013-03/0103.html . libunbound may be the correct library to base this development on. Björn Stenberg wrote a separate initial take on DANE that was never completed. +13.9 TLS record padding + + TLS (1.3) offers optional record padding and OpenSSL provides an API for it. + I could make sense for libcurl to offer this ability to applications to make + traffic patterns harder to figure out by network traffic observers. + + See https://github.com/curl/curl/issues/5398 + 13.10 Support Authority Information Access certificate extension (AIA) AIA can provide various things like CRLs but more importantly information about intermediate CA certificates that can allow validation path to be - fulfilled when the HTTPS server doesn't itself provide them. + fulfilled when the HTTPS server does not itself provide them. Since AIA is about downloading certs on demand to complete a TLS handshake, it is probably a bit tricky to get done right. @@ -719,31 +838,28 @@ that doesn't exist on the server, just like --ftp-create-dirs. CURLOPT_PINNEDPUBLICKEY does not consider the hashes of intermediate & root certificates when comparing the pinned keys. Therefore it is not compatible - with "HTTP Public Key Pinning" as there also intermediate and root certificates - can be pinned. This is very useful as it prevents webadmins from "locking - themself out of their servers". + with "HTTP Public Key Pinning" as there also intermediate and root + certificates can be pinned. This is useful as it prevents webadmins from + "locking themselves out of their servers". - Adding this feature would make curls pinning 100% compatible to HPKP and allow - more flexible pinning. + Adding this feature would make curls pinning 100% compatible to HPKP and + allow more flexible pinning. -13.12 Support HSTS +13.13 Make sure we forbid TLS 1.3 post-handshake authentication - "HTTP Strict Transport Security" is TOFU (trust on first use), time-based - features indicated by a HTTP header send by the webserver. It is widely used - in browsers and it's purpose is to prevent insecure HTTP connections after - a previous HTTPS connection. It protects against SSLStripping attacks. + RFC 8740 explains how using HTTP/2 must forbid the use of TLS 1.3 + post-handshake authentication. We should make sure to live up to that. - Doc: https://developer.mozilla.org/en-US/docs/Web/Security/HTTP_strict_transport_security - RFC 6797: https://tools.ietf.org/html/rfc6797 + See https://github.com/curl/curl/issues/5396 13.14 Support the clienthello extension Certain stupid networks and middle boxes have a problem with SSL handshake - pakets that are within a certain size range because how that sets some bits + packets that are within a certain size range because how that sets some bits that previously (in older TLS version) were not set. The clienthello extension adds padding to avoid that size range. - https://tools.ietf.org/html/rfc7685 + https://datatracker.ietf.org/doc/html/rfc7685 https://github.com/curl/curl/issues/2299 14. GnuTLS @@ -753,42 +869,30 @@ that doesn't exist on the server, just like --ftp-create-dirs. Add a way to check if the connection seems to be alive, to correspond to the SSL_peak() way we use with OpenSSL. -15. WinSSL/SChannel - -15.1 Add support for client certificate authentication +15. Schannel - WinSSL/SChannel currently makes use of the OS-level system and user - certificate and private key stores. This does not allow the application - or the user to supply a custom client certificate using curl or libcurl. +15.1 Extend support for client certificate authentication - Therefore support for the existing -E/--cert and --key options should be - implemented by supplying a custom certificate to the SChannel APIs, see: + The existing support for the -E/--cert and --key options could be + extended by supplying a custom certificate and key in PEM format, see: - Getting a Certificate for Schannel https://msdn.microsoft.com/en-us/library/windows/desktop/aa375447.aspx -15.3 Add support for the --ciphers option - - The cipher suites used by WinSSL/SChannel are configured on an OS-level - instead of an application-level. This does not allow the application or - the user to customize the configured cipher suites using curl or libcurl. +15.2 Extend support for the --ciphers option - Therefore support for the existing --ciphers option should be implemented - by mapping the OpenSSL/GnuTLS cipher suites to the SChannel APIs, see + The existing support for the --ciphers option could be extended + by mapping the OpenSSL/GnuTLS cipher suites to the Schannel APIs, see - Specifying Schannel Ciphers and Cipher Strengths https://msdn.microsoft.com/en-us/library/windows/desktop/aa380161.aspx -15.4 Add option to disable client certificate auto-send +15.4 Add option to allow abrupt server closure - Microsoft says "By default, Schannel will, with no notification to the client, - attempt to locate a client certificate and send it to the server." That could - be considered a privacy violation and unexpected. + libcurl w/schannel will error without a known termination point from the + server (such as length of transfer, or SSL "close notify" alert) to prevent + against a truncation attack. Really old servers may neglect to send any + termination point. An option could be added to ignore such abrupt closures. - Some Windows users have come to expect that default behavior and to change the - default to make it consistent with other SSL backends would be a breaking - change. An option should be added that can be used to disable the default - Schannel auto-send behavior. - - https://github.com/curl/curl/issues/2262 + https://github.com/curl/curl/issues/4427 16. SASL @@ -804,10 +908,6 @@ that doesn't exist on the server, just like --ftp-create-dirs. with integrity protection) and auth-conf (Authentication with integrity and privacy protection). -16.3 Support binary messages (i.e.: non-base64) - - Mandatory to support LDAP SASL authentication. - 17. SSH protocols @@ -826,25 +926,37 @@ that doesn't exist on the server, just like --ftp-create-dirs. The SFTP code in libcurl checks the file size *before* a transfer starts and then proceeds to transfer exactly that amount of data. If the remote file - grows while the transfer is in progress libcurl won't notice and will not + grows while the transfer is in progress libcurl will not notice and will not adapt. The OpenSSH SFTP command line tool does and libcurl could also just attempt to download more to see if there is more to get... https://github.com/curl/curl/issues/4344 -17.3 Support better than MD5 hostkey hash +17.3 Read keys from ~/.ssh/id_ecdsa, id_ed25519 + + The libssh2 backend in curl is limited to only reading keys from id_rsa and + id_dsa, which makes it fail connecting to servers that use more modern key + types. - libcurl offers the CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 option for verifying the - server's key. MD5 is generally being deprecated so we should implement - support for stronger hashing algorithms. libssh2 itself is what provides this - underlying functionality and it supports at least SHA-1 as an alternative. - SHA-1 is also being deprecated these days so we should consider working with - libssh2 to instead offer support for SHA-256 or similar. + https://github.com/curl/curl/issues/8586 17.4 Support CURLOPT_PREQUOTE The two other QUOTE options are supported for SFTP, but this was left out for - unknown reasons! + unknown reasons. + +17.5 SSH over HTTPS proxy with more backends + + The SSH based protocols SFTP and SCP did not work over HTTPS proxy at + all until PR https://github.com/curl/curl/pull/6021 brought the + functionality with the libssh2 backend. Presumably, this support + can/could be added for the other backends as well. + +17.6 SFTP with SCP:// + + OpenSSH 9 switched their 'scp' tool to speak SFTP under the hood. Going + forward it might be worth having curl or libcurl attempt SFTP if SCP fails to + follow suite. 18. Command line tool @@ -862,14 +974,6 @@ that doesn't exist on the server, just like --ftp-create-dirs. Globbing support for -d and -F, as in 'curl -d "name=foo[0-9]" URL'. This is easily scripted though. -18.3 prevent file overwriting - - Add an option that prevents curl from overwriting existing local files. When - used, and there already is an existing file with the target file name - (either -O or -o), a number should be appended (and increased if already - existing). So that index.html becomes first index.html.1 and then - index.html.2 etc. - 18.4 --proxycommand Allow the user to make curl run a command and use its stdio to make requests @@ -887,6 +991,14 @@ that doesn't exist on the server, just like --ftp-create-dirs. https://github.com/curl/curl/issues/1888 +18.6 Option to make -Z merge lined based outputs on stdout + + When a user requests multiple lined based files using -Z and sends them to + stdout, curl will not "merge" and send complete lines fine but may send + partial lines from several sources. + + https://github.com/curl/curl/issues/5175 + 18.7 at least N milliseconds between requests Allow curl command lines issue a lot of request against services that limit @@ -898,6 +1010,20 @@ that doesn't exist on the server, just like --ftp-create-dirs. See https://github.com/curl/curl/issues/3920 +18.8 Consider convenience options for JSON and XML? + + Could we add `--xml` or `--json` to add headers needed to call rest API: + + `--xml` adds -H 'Content-Type: application/xml' -H "Accept: application/xml" and + `--json` adds -H 'Content-Type: application/json' -H "Accept: application/json" + + Setting Content-Type when doing a GET or any other method without a body + would be a bit strange I think - so maybe only add CT for requests with body? + Maybe plain `--xml` and ` --json` are a bit too brief and generic. Maybe + `--http-json` etc? + + See https://github.com/curl/curl/issues/5203 + 18.9 Choose the name of file in braces for complex URLs When using braces to download a list of URLs and you use complicated names @@ -935,11 +1061,28 @@ that doesn't exist on the server, just like --ftp-create-dirs. invoke can talk to the still running instance and ask for transfers to get done, and thus maintain its connection pool, DNS cache and more. +18.13 Ratelimit or wait between serial requests + + Consider a command line option that can make curl do multiple serial requests + slow, potentially with a (random) wait between transfers. There's also a + proposed set of standard HTTP headers to let servers let the client adapt to + its rate limits: + https://www.ietf.org/id/draft-polli-ratelimit-headers-02.html + + See https://github.com/curl/curl/issues/5406 + +18.14 --dry-run + + A command line option that makes curl show exactly what it would do and send + if it would run for real. + + See https://github.com/curl/curl/issues/5426 + 18.15 --retry should resume When --retry is used and curl actually retries transfer, it should use the already transferred data and do a resumed transfer for the rest (when - possible) so that it doesn't have to transfer the same data again that was + possible) so that it does not have to transfer the same data again that was already transferred before the retry. See https://github.com/curl/curl/issues/1084 @@ -966,7 +1109,7 @@ that doesn't exist on the server, just like --ftp-create-dirs. provides the "may overwrite any file" risk. This is extra tricky if the original URL has no file name part at all since - then the current code path will error out with an error message, and we can't + then the current code path will error out with an error message, and we cannot *know* already at that point if curl will be redirected to a URL that has a file name... @@ -997,6 +1140,60 @@ that doesn't exist on the server, just like --ftp-create-dirs. default .curlrc could a specific user-agent only when doing requests against a certain site. +18.21 retry on the redirected-to URL + + When curl is told to --retry a failed transfer and follows redirects, it + might get an HTTP 429 response from the redirected-to URL and not the + original one, which then could make curl decide to rather retry the transfer + on that URL only instead of the original operation to the original URL. + + Perhaps extra emphasized if the original transfer is a large POST that + redirects to a separate GET, and that GET is what gets the 529 + + See https://github.com/curl/curl/issues/5462 + +18.23 Set the modification date on an uploaded file + + For SFTP and possibly FTP, curl could offer an option to set the + modification time for the uploaded file. + + See https://github.com/curl/curl/issues/5768 + +18.24 Use multiple parallel transfers for a single download + + To enhance transfer speed, downloading a single URL can be split up into + multiple separate range downloads that get combined into a single final + result. + + An ideal implementation would not use a specified number of parallel + transfers, but curl could: + - First start getting the full file as transfer A + - If after N seconds have passed and the transfer is expected to continue for + M seconds or more, add a new transfer (B) that asks for the second half of + A's content (and stop A at the middle). + - If splitting up the work improves the transfer rate, it could then be done + again. Then again, etc up to a limit. + + This way, if transfer B fails (because Range: is not supported) it will let + transfer A remain the single one. N and M could be set to some sensible + defaults. + + See https://github.com/curl/curl/issues/5774 + +18.25 Prevent terminal injection when writing to terminal + + curl could offer an option to make escape sequence either non-functional or + avoid cursor moves or similar to reduce the risk of a user getting tricked by + clever tricks. + + See https://github.com/curl/curl/issues/6150 + +18.26 Custom progress meter update interval + + Users who are for example doing large downloads in CI or remote setups might + want the occasional progress meter update to see that the transfer is + progressing and has not stuck, but they may not appreciate the + many-times-a-second frequency curl can end up doing it with now. 19. Build @@ -1017,13 +1214,26 @@ that doesn't exist on the server, just like --ftp-create-dirs. to no impact, neither on the performance nor on the general functionality of curl. -19.3 cmake test suite improvements +19.3 Do not use GNU libtool on OpenBSD + When compiling curl on OpenBSD with "--enable-debug" it will give linking + errors when you use GNU libtool. This can be fixed by using the libtool + provided by OpenBSD itself. However for this the user always needs to invoke + make with "LIBTOOL=/usr/bin/libtool". It would be nice if the script could + have some magic to detect if this system is an OpenBSD host and then use the + OpenBSD libtool instead. + + See https://github.com/curl/curl/issues/5862 + +19.4 Package curl for Windows in a signed installer - The cmake build doesn't support 'make show' so it doesn't know which tests - are in the makefile or not (making appveyor builds do many false warnings - about it) nor does it support running the test suite if building out-of-tree. + See https://github.com/curl/curl/issues/5424 - See https://github.com/curl/curl/issues/3109 +19.5 make configure use --cache-file more and better + + The configure script can be improved to cache more values so that repeated + invokes run much faster. + + See https://github.com/curl/curl/issues/7753 20. Test suite @@ -1035,8 +1245,8 @@ that doesn't exist on the server, just like --ftp-create-dirs. 20.2 nicer lacking perl message - If perl wasn't found by the configure script, don't attempt to run the tests - but explain something nice why it doesn't. + If perl was not found by the configure script, do not attempt to run the tests + but explain something nice why it does not. 20.3 more protocols supported @@ -1051,15 +1261,15 @@ that doesn't exist on the server, just like --ftp-create-dirs. 20.5 Add support for concurrent connections Tests 836, 882 and 938 were designed to verify that separate connections - aren't used when using different login credentials in protocols that - shouldn't re-use a connection under such circumstances. + are not used when using different login credentials in protocols that + should not re-use a connection under such circumstances. - Unfortunately, ftpserver.pl doesn't appear to support multiple concurrent + Unfortunately, ftpserver.pl does not appear to support multiple concurrent connections. The read while() loop seems to loop until it receives a disconnect from the client, where it then enters the waiting for connections loop. When the client opens a second connection to the server, the first - connection hasn't been dropped (unless it has been forced - which we - shouldn't do in these tests) and thus the wait for connections loop is never + connection has not been dropped (unless it has been forced - which we + should not do in these tests) and thus the wait for connections loop is never entered to receive the second connection. 20.6 Use the RFC6265 test suite @@ -1073,114 +1283,22 @@ that doesn't exist on the server, just like --ftp-create-dirs. 20.7 Support LD_PRELOAD on macOS - LD_RELOAD doesn't work on macOS, but there are tests which require it to run + LD_RELOAD does not work on macOS, but there are tests which require it to run properly. Look into making the preload support in runtests.pl portable such that it uses DYLD_INSERT_LIBRARIES on macOS. -20.8 Run web-platform-tests url tests +20.8 Run web-platform-tests URL tests - Run web-platform-tests url tests and compare results with browsers on wpt.fyi + Run web-platform-tests URL tests and compare results with browsers on wpt.fyi It would help us find issues to fix and help us document where our parser differs from the WHATWG URL spec parsers. See https://github.com/curl/curl/issues/4477 -21. Next SONAME bump - -21.1 http-style HEAD output for FTP - - #undef CURL_FTP_HTTPSTYLE_HEAD in lib/ftp.c to remove the HTTP-style headers - from being output in NOBODY requests over FTP - -21.2 combine error codes - - Combine some of the error codes to remove duplicates. The original - numbering should not be changed, and the old identifiers would be - macroed to the new ones in an CURL_NO_OLDIES section to help with - backward compatibility. - - Candidates for removal and their replacements: - - CURLE_FILE_COULDNT_READ_FILE => CURLE_REMOTE_FILE_NOT_FOUND - - CURLE_FTP_COULDNT_RETR_FILE => CURLE_REMOTE_FILE_NOT_FOUND - - CURLE_FTP_COULDNT_USE_REST => CURLE_RANGE_ERROR - - CURLE_FUNCTION_NOT_FOUND => CURLE_FAILED_INIT - - CURLE_LDAP_INVALID_URL => CURLE_URL_MALFORMAT - - CURLE_TFTP_NOSUCHUSER => CURLE_TFTP_ILLEGAL - - CURLE_TFTP_NOTFOUND => CURLE_REMOTE_FILE_NOT_FOUND - - CURLE_TFTP_PERM => CURLE_REMOTE_ACCESS_DENIED - -21.3 extend CURLOPT_SOCKOPTFUNCTION prototype - - The current prototype only provides 'purpose' that tells what the - connection/socket is for, but not any protocol or similar. It makes it hard - for applications to differentiate on TCP vs UDP and even HTTP vs FTP and - similar. - -22. Next major release - -22.1 cleanup return codes - - curl_easy_cleanup() returns void, but curl_multi_cleanup() returns a - CURLMcode. These should be changed to be the same. - -22.2 remove obsolete defines - - remove obsolete defines from curl/curl.h - -22.3 size_t - - make several functions use size_t instead of int in their APIs - -22.4 remove several functions - - remove the following functions from the public API: - - curl_getenv - - curl_mprintf (and variations) - - curl_strequal - - curl_strnequal - - They will instead become curlx_ - alternatives. That makes the curl app - still capable of using them, by building with them from source. - - These functions have no purpose anymore: - - curl_multi_socket - - curl_multi_socket_all - -22.5 remove CURLOPT_FAILONERROR - - Remove support for CURLOPT_FAILONERROR, it has gotten too kludgy and weird - internally. Let the app judge success or not for itself. - -22.7 remove progress meter from libcurl - - The internally provided progress meter output doesn't belong in the library. - Basically no application wants it (apart from curl) but instead applications - can and should do their own progress meters using the progress callback. - - The progress callback should then be bumped as well to get proper 64bit - variable types passed to it instead of doubles so that big files work - correctly. - -22.8 remove 'curl_httppost' from public +21. MQTT - curl_formadd() was made to fill in a public struct, but the fact that the - struct is public is never really used by application for their own advantage - but instead often restricts how the form functions can or can't be modified. +21.1 Support rate-limiting - Changing them to return a private handle will benefit the implementation and - allow us much greater freedoms while still maintaining a solid API and ABI. + The rate-limiting logic is done in the PERFORMING state in multi.c but MQTT + is not (yet) implemented to use that. diff --git a/extern/curl/docs/TheArtOfHttpScripting b/extern/curl/docs/TheArtOfHttpScripting deleted file mode 100644 index c5b67ca1b5..0000000000 --- a/extern/curl/docs/TheArtOfHttpScripting +++ /dev/null @@ -1,758 +0,0 @@ - _ _ ____ _ - ___| | | | _ \| | - / __| | | | |_) | | - | (__| |_| | _ <| |___ - \___|\___/|_| \_\_____| - - -The Art Of Scripting HTTP Requests Using Curl - - 1. HTTP Scripting - 1.1 Background - 1.2 The HTTP Protocol - 1.3 See the Protocol - 1.4 See the Timing - 1.5 See the Response - 2. URL - 2.1 Spec - 2.2 Host - 2.3 Port number - 2.4 User name and password - 2.5 Path part - 3. Fetch a page - 3.1 GET - 3.2 HEAD - 3.3 Multiple URLs in a single command line - 3.4 Multiple HTTP methods in a single command line - 4. HTML forms - 4.1 Forms explained - 4.2 GET - 4.3 POST - 4.4 File Upload POST - 4.5 Hidden Fields - 4.6 Figure Out What A POST Looks Like - 5. HTTP upload - 5.1 PUT - 6. HTTP Authentication - 6.1 Basic Authentication - 6.2 Other Authentication - 6.3 Proxy Authentication - 6.4 Hiding credentials - 7. More HTTP Headers - 7.1 Referer - 7.2 User Agent - 8. Redirects - 8.1 Location header - 8.2 Other redirects - 9. Cookies - 9.1 Cookie Basics - 9.2 Cookie options - 10. HTTPS - 10.1 HTTPS is HTTP secure - 10.2 Certificates - 11. Custom Request Elements - 11.1 Modify method and headers - 11.2 More on changed methods - 12. Web Login - 12.1 Some login tricks - 13. Debug - 13.1 Some debug tricks - 14. References - 14.1 Standards - 14.2 Sites - -============================================================================== - -1. HTTP Scripting - - 1.1 Background - - This document assumes that you're familiar with HTML and general networking. - - The increasing amount of applications moving to the web has made "HTTP - Scripting" more frequently requested and wanted. To be able to automatically - extract information from the web, to fake users, to post or upload data to - web servers are all important tasks today. - - Curl is a command line tool for doing all sorts of URL manipulations and - transfers, but this particular document will focus on how to use it when - doing HTTP requests for fun and profit. I'll assume that you know how to - invoke 'curl --help' or 'curl --manual' to get basic information about it. - - Curl is not written to do everything for you. It makes the requests, it gets - the data, it sends data and it retrieves the information. You probably need - to glue everything together using some kind of script language or repeated - manual invokes. - - 1.2 The HTTP Protocol - - HTTP is the protocol used to fetch data from web servers. It is a very simple - protocol that is built upon TCP/IP. The protocol also allows information to - get sent to the server from the client using a few different methods, as will - be shown here. - - HTTP is plain ASCII text lines being sent by the client to a server to - request a particular action, and then the server replies a few text lines - before the actual requested content is sent to the client. - - The client, curl, sends a HTTP request. The request contains a method (like - GET, POST, HEAD etc), a number of request headers and sometimes a request - body. The HTTP server responds with a status line (indicating if things went - well), response headers and most often also a response body. The "body" part - is the plain data you requested, like the actual HTML or the image etc. - - 1.3 See the Protocol - - Using curl's option --verbose (-v as a short option) will display what kind - of commands curl sends to the server, as well as a few other informational - texts. - - --verbose is the single most useful option when it comes to debug or even - understand the curl<->server interaction. - - Sometimes even --verbose is not enough. Then --trace and --trace-ascii offer - even more details as they show EVERYTHING curl sends and receives. Use it - like this: - - curl --trace-ascii debugdump.txt http://www.example.com/ - - 1.4 See the Timing - - Many times you may wonder what exactly is taking all the time, or you just - want to know the amount of milliseconds between two points in a - transfer. For those, and other similar situations, the --trace-time option - is what you need. It'll prepend the time to each trace output line: - - curl --trace-ascii d.txt --trace-time http://example.com/ - - 1.5 See the Response - - By default curl sends the response to stdout. You need to redirect it - somewhere to avoid that, most often that is done with -o or -O. - -2. URL - - 2.1 Spec - - The Uniform Resource Locator format is how you specify the address of a - particular resource on the Internet. You know these, you've seen URLs like - https://curl.haxx.se or https://yourbank.com a million times. RFC 3986 is the - canonical spec. And yeah, the formal name is not URL, it is URI. - - 2.2 Host - - The host name is usually resolved using DNS or your /etc/hosts file to an IP - address and that's what curl will communicate with. Alternatively you specify - the IP address directly in the URL instead of a name. - - For development and other trying out situations, you can point to a different - IP address for a host name than what would otherwise be used, by using curl's - --resolve option: - - curl --resolve www.example.org:80:127.0.0.1 http://www.example.org/ - - 2.3 Port number - - Each protocol curl supports operates on a default port number, be it over TCP - or in some cases UDP. Normally you don't have to take that into - consideration, but at times you run test servers on other ports or - similar. Then you can specify the port number in the URL with a colon and a - number immediately following the host name. Like when doing HTTP to port - 1234: - - curl http://www.example.org:1234/ - - The port number you specify in the URL is the number that the server uses to - offer its services. Sometimes you may use a local proxy, and then you may - need to specify that proxy's port number separately for what curl needs to - connect to locally. Like when using a HTTP proxy on port 4321: - - curl --proxy http://proxy.example.org:4321 http://remote.example.org/ - - 2.4 User name and password - - Some services are setup to require HTTP authentication and then you need to - provide name and password which is then transferred to the remote site in - various ways depending on the exact authentication protocol used. - - You can opt to either insert the user and password in the URL or you can - provide them separately: - - curl http://user:password@example.org/ - - or - - curl -u user:password http://example.org/ - - You need to pay attention that this kind of HTTP authentication is not what - is usually done and requested by user-oriented web sites these days. They - tend to use forms and cookies instead. - - 2.5 Path part - - The path part is just sent off to the server to request that it sends back - the associated response. The path is what is to the right side of the slash - that follows the host name and possibly port number. - -3. Fetch a page - - 3.1 GET - - The simplest and most common request/operation made using HTTP is to GET a - URL. The URL could itself refer to a web page, an image or a file. The client - issues a GET request to the server and receives the document it asked for. - If you issue the command line - - curl https://curl.haxx.se - - you get a web page returned in your terminal window. The entire HTML document - that that URL holds. - - All HTTP replies contain a set of response headers that are normally hidden, - use curl's --include (-i) option to display them as well as the rest of the - document. - - 3.2 HEAD - - You can ask the remote server for ONLY the headers by using the --head (-I) - option which will make curl issue a HEAD request. In some special cases - servers deny the HEAD method while others still work, which is a particular - kind of annoyance. - - The HEAD method is defined and made so that the server returns the headers - exactly the way it would do for a GET, but without a body. It means that you - may see a Content-Length: in the response headers, but there must not be an - actual body in the HEAD response. - - 3.3 Multiple URLs in a single command line - - A single curl command line may involve one or many URLs. The most common case - is probably to just use one, but you can specify any amount of URLs. Yes - any. No limits. You'll then get requests repeated over and over for all the - given URLs. - - Example, send two GETs: - - curl http://url1.example.com http://url2.example.com - - If you use --data to POST to the URL, using multiple URLs means that you send - that same POST to all the given URLs. - - Example, send two POSTs: - - curl --data name=curl http://url1.example.com http://url2.example.com - - - 3.4 Multiple HTTP methods in a single command line - - Sometimes you need to operate on several URLs in a single command line and do - different HTTP methods on each. For this, you'll enjoy the --next option. It - is basically a separator that separates a bunch of options from the next. All - the URLs before --next will get the same method and will get all the POST - data merged into one. - - When curl reaches the --next on the command line, it'll sort of reset the - method and the POST data and allow a new set. - - Perhaps this is best shown with a few examples. To send first a HEAD and then - a GET: - - curl -I http://example.com --next http://example.com - - To first send a POST and then a GET: - - curl -d score=10 http://example.com/post.cgi --next http://example.com/results.html - - -4. HTML forms - - 4.1 Forms explained - - Forms are the general way a web site can present a HTML page with fields for - the user to enter data in, and then press some kind of 'OK' or 'Submit' - button to get that data sent to the server. The server then typically uses - the posted data to decide how to act. Like using the entered words to search - in a database, or to add the info in a bug tracking system, display the entered - address on a map or using the info as a login-prompt verifying that the user - is allowed to see what it is about to see. - - Of course there has to be some kind of program on the server end to receive - the data you send. You cannot just invent something out of the air. - - 4.2 GET - - A GET-form uses the method GET, as specified in HTML like: - -
- - -
- - In your favorite browser, this form will appear with a text box to fill in - and a press-button labeled "OK". If you fill in '1905' and press the OK - button, your browser will then create a new URL to get for you. The URL will - get "junk.cgi?birthyear=1905&press=OK" appended to the path part of the - previous URL. - - If the original form was seen on the page "www.hotmail.com/when/birth.html", - the second page you'll get will become - "www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK". - - Most search engines work this way. - - To make curl do the GET form post for you, just enter the expected created - URL: - - curl "http://www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK" - - 4.3 POST - - The GET method makes all input field names get displayed in the URL field of - your browser. That's generally a good thing when you want to be able to - bookmark that page with your given data, but it is an obvious disadvantage - if you entered secret information in one of the fields or if there are a - large amount of fields creating a very long and unreadable URL. - - The HTTP protocol then offers the POST method. This way the client sends the - data separated from the URL and thus you won't see any of it in the URL - address field. - - The form would look very similar to the previous one: - -
- - -
- - And to use curl to post this form with the same data filled in as before, we - could do it like: - - curl --data "birthyear=1905&press=%20OK%20" \ - http://www.example.com/when.cgi - - This kind of POST will use the Content-Type - application/x-www-form-urlencoded and is the most widely used POST kind. - - The data you send to the server MUST already be properly encoded, curl will - not do that for you. For example, if you want the data to contain a space, - you need to replace that space with %20 etc. Failing to comply with this - will most likely cause your data to be received wrongly and messed up. - - Recent curl versions can in fact url-encode POST data for you, like this: - - curl --data-urlencode "name=I am Daniel" http://www.example.com - - If you repeat --data several times on the command line, curl will - concatenate all the given data pieces - and put a '&' symbol between each - data segment. - - 4.4 File Upload POST - - Back in late 1995 they defined an additional way to post data over HTTP. It - is documented in the RFC 1867, why this method sometimes is referred to as - RFC1867-posting. - - This method is mainly designed to better support file uploads. A form that - allows a user to upload a file could be written like this in HTML: - -
- - -
- - This clearly shows that the Content-Type about to be sent is - multipart/form-data. - - To post to a form like this with curl, you enter a command line like: - - curl --form upload=@localfilename --form press=OK [URL] - - 4.5 Hidden Fields - - A very common way for HTML based applications to pass state information - between pages is to add hidden fields to the forms. Hidden fields are - already filled in, they aren't displayed to the user and they get passed - along just as all the other fields. - - A similar example form with one visible field, one hidden field and one - submit button could look like: - -
- - - -
- - To POST this with curl, you won't have to think about if the fields are - hidden or not. To curl they're all the same: - - curl --data "birthyear=1905&press=OK&person=daniel" [URL] - - 4.6 Figure Out What A POST Looks Like - - When you're about fill in a form and send to a server by using curl instead - of a browser, you're of course very interested in sending a POST exactly the - way your browser does. - - An easy way to get to see this, is to save the HTML page with the form on - your local disk, modify the 'method' to a GET, and press the submit button - (you could also change the action URL if you want to). - - You will then clearly see the data get appended to the URL, separated with a - '?'-letter as GET forms are supposed to. - -5. HTTP upload - - 5.1 PUT - - Perhaps the best way to upload data to a HTTP server is to use PUT. Then - again, this of course requires that someone put a program or script on the - server end that knows how to receive a HTTP PUT stream. - - Put a file to a HTTP server with curl: - - curl --upload-file uploadfile http://www.example.com/receive.cgi - -6. HTTP Authentication - - 6.1 Basic Authentication - - HTTP Authentication is the ability to tell the server your username and - password so that it can verify that you're allowed to do the request you're - doing. The Basic authentication used in HTTP (which is the type curl uses by - default) is *plain* *text* based, which means it sends username and password - only slightly obfuscated, but still fully readable by anyone that sniffs on - the network between you and the remote server. - - To tell curl to use a user and password for authentication: - - curl --user name:password http://www.example.com - - 6.2 Other Authentication - - The site might require a different authentication method (check the headers - returned by the server), and then --ntlm, --digest, --negotiate or even - --anyauth might be options that suit you. - - 6.3 Proxy Authentication - - Sometimes your HTTP access is only available through the use of a HTTP - proxy. This seems to be especially common at various companies. A HTTP proxy - may require its own user and password to allow the client to get through to - the Internet. To specify those with curl, run something like: - - curl --proxy-user proxyuser:proxypassword curl.haxx.se - - If your proxy requires the authentication to be done using the NTLM method, - use --proxy-ntlm, if it requires Digest use --proxy-digest. - - If you use any one of these user+password options but leave out the password - part, curl will prompt for the password interactively. - - 6.4 Hiding credentials - - Do note that when a program is run, its parameters might be possible to see - when listing the running processes of the system. Thus, other users may be - able to watch your passwords if you pass them as plain command line - options. There are ways to circumvent this. - - It is worth noting that while this is how HTTP Authentication works, very - many web sites will not use this concept when they provide logins etc. See - the Web Login chapter further below for more details on that. - -7. More HTTP Headers - - 7.1 Referer - - A HTTP request may include a 'referer' field (yes it is misspelled), which - can be used to tell from which URL the client got to this particular - resource. Some programs/scripts check the referer field of requests to verify - that this wasn't arriving from an external site or an unknown page. While - this is a stupid way to check something so easily forged, many scripts still - do it. Using curl, you can put anything you want in the referer-field and - thus more easily be able to fool the server into serving your request. - - Use curl to set the referer field with: - - curl --referer http://www.example.come http://www.example.com - - 7.2 User Agent - - Very similar to the referer field, all HTTP requests may set the User-Agent - field. It names what user agent (client) that is being used. Many - applications use this information to decide how to display pages. Silly web - programmers try to make different pages for users of different browsers to - make them look the best possible for their particular browsers. They usually - also do different kinds of javascript, vbscript etc. - - At times, you will see that getting a page with curl will not return the same - page that you see when getting the page with your browser. Then you know it - is time to set the User Agent field to fool the server into thinking you're - one of those browsers. - - To make curl look like Internet Explorer 5 on a Windows 2000 box: - - curl --user-agent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" [URL] - - Or why not look like you're using Netscape 4.73 on an old Linux box: - - curl --user-agent "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" [URL] - -8. Redirects - - 8.1 Location header - - When a resource is requested from a server, the reply from the server may - include a hint about where the browser should go next to find this page, or a - new page keeping newly generated output. The header that tells the browser - to redirect is Location:. - - Curl does not follow Location: headers by default, but will simply display - such pages in the same manner it displays all HTTP replies. It does however - feature an option that will make it attempt to follow the Location: pointers. - - To tell curl to follow a Location: - - curl --location http://www.example.com - - If you use curl to POST to a site that immediately redirects you to another - page, you can safely use --location (-L) and --data/--form together. Curl will - only use POST in the first request, and then revert to GET in the following - operations. - - 8.2 Other redirects - - Browser typically support at least two other ways of redirects that curl - doesn't: first the html may contain a meta refresh tag that asks the browser - to load a specific URL after a set number of seconds, or it may use - javascript to do it. - -9. Cookies - - 9.1 Cookie Basics - - The way the web browsers do "client side state control" is by using - cookies. Cookies are just names with associated contents. The cookies are - sent to the client by the server. The server tells the client for what path - and host name it wants the cookie sent back, and it also sends an expiration - date and a few more properties. - - When a client communicates with a server with a name and path as previously - specified in a received cookie, the client sends back the cookies and their - contents to the server, unless of course they are expired. - - Many applications and servers use this method to connect a series of requests - into a single logical session. To be able to use curl in such occasions, we - must be able to record and send back cookies the way the web application - expects them. The same way browsers deal with them. - - 9.2 Cookie options - - The simplest way to send a few cookies to the server when getting a page with - curl is to add them on the command line like: - - curl --cookie "name=Daniel" http://www.example.com - - Cookies are sent as common HTTP headers. This is practical as it allows curl - to record cookies simply by recording headers. Record cookies with curl by - using the --dump-header (-D) option like: - - curl --dump-header headers_and_cookies http://www.example.com - - (Take note that the --cookie-jar option described below is a better way to - store cookies.) - - Curl has a full blown cookie parsing engine built-in that comes in use if you - want to reconnect to a server and use cookies that were stored from a - previous connection (or hand-crafted manually to fool the server into - believing you had a previous connection). To use previously stored cookies, - you run curl like: - - curl --cookie stored_cookies_in_file http://www.example.com - - Curl's "cookie engine" gets enabled when you use the --cookie option. If you - only want curl to understand received cookies, use --cookie with a file that - doesn't exist. Example, if you want to let curl understand cookies from a - page and follow a location (and thus possibly send back cookies it received), - you can invoke it like: - - curl --cookie nada --location http://www.example.com - - Curl has the ability to read and write cookie files that use the same file - format that Netscape and Mozilla once used. It is a convenient way to share - cookies between scripts or invokes. The --cookie (-b) switch automatically - detects if a given file is such a cookie file and parses it, and by using the - --cookie-jar (-c) option you'll make curl write a new cookie file at the end - of an operation: - - curl --cookie cookies.txt --cookie-jar newcookies.txt \ - http://www.example.com - -10. HTTPS - - 10.1 HTTPS is HTTP secure - - There are a few ways to do secure HTTP transfers. By far the most common - protocol for doing this is what is generally known as HTTPS, HTTP over - SSL. SSL encrypts all the data that is sent and received over the network and - thus makes it harder for attackers to spy on sensitive information. - - SSL (or TLS as the latest version of the standard is called) offers a - truckload of advanced features to allow all those encryptions and key - infrastructure mechanisms encrypted HTTP requires. - - Curl supports encrypted fetches when built to use a TLS library and it can be - built to use one out of a fairly large set of libraries - "curl -V" will show - which one your curl was built to use (if any!). To get a page from a HTTPS - server, simply run curl like: - - curl https://secure.example.com - - 10.2 Certificates - - In the HTTPS world, you use certificates to validate that you are the one - you claim to be, as an addition to normal passwords. Curl supports client- - side certificates. All certificates are locked with a pass phrase, which you - need to enter before the certificate can be used by curl. The pass phrase - can be specified on the command line or if not, entered interactively when - curl queries for it. Use a certificate with curl on a HTTPS server like: - - curl --cert mycert.pem https://secure.example.com - - curl also tries to verify that the server is who it claims to be, by - verifying the server's certificate against a locally stored CA cert - bundle. Failing the verification will cause curl to deny the connection. You - must then use --insecure (-k) in case you want to tell curl to ignore that - the server can't be verified. - - More about server certificate verification and ca cert bundles can be read - in the SSLCERTS document, available online here: - - https://curl.haxx.se/docs/sslcerts.html - - At times you may end up with your own CA cert store and then you can tell - curl to use that to verify the server's certificate: - - curl --cacert ca-bundle.pem https://example.com/ - - -11. Custom Request Elements - -11.1 Modify method and headers - - Doing fancy stuff, you may need to add or change elements of a single curl - request. - - For example, you can change the POST request to a PROPFIND and send the data - as "Content-Type: text/xml" (instead of the default Content-Type) like this: - - curl --data "" --header "Content-Type: text/xml" \ - --request PROPFIND url.com - - You can delete a default header by providing one without content. Like you - can ruin the request by chopping off the Host: header: - - curl --header "Host:" http://www.example.com - - You can add headers the same way. Your server may want a "Destination:" - header, and you can add it: - - curl --header "Destination: http://nowhere" http://example.com - - 11.2 More on changed methods - - It should be noted that curl selects which methods to use on its own - depending on what action to ask for. -d will do POST, -I will do HEAD and so - on. If you use the --request / -X option you can change the method keyword - curl selects, but you will not modify curl's behavior. This means that if you - for example use -d "data" to do a POST, you can modify the method to a - PROPFIND with -X and curl will still think it sends a POST. You can change - the normal GET to a POST method by simply adding -X POST in a command line - like: - - curl -X POST http://example.org/ - - ... but curl will still think and act as if it sent a GET so it won't send any - request body etc. - - -12. Web Login - - 12.1 Some login tricks - - While not strictly just HTTP related, it still causes a lot of people problems - so here's the executive run-down of how the vast majority of all login forms - work and how to login to them using curl. - - It can also be noted that to do this properly in an automated fashion, you - will most certainly need to script things and do multiple curl invokes etc. - - First, servers mostly use cookies to track the logged-in status of the - client, so you will need to capture the cookies you receive in the - responses. Then, many sites also set a special cookie on the login page (to - make sure you got there through their login page) so you should make a habit - of first getting the login-form page to capture the cookies set there. - - Some web-based login systems feature various amounts of javascript, and - sometimes they use such code to set or modify cookie contents. Possibly they - do that to prevent programmed logins, like this manual describes how to... - Anyway, if reading the code isn't enough to let you repeat the behavior - manually, capturing the HTTP requests done by your browsers and analyzing the - sent cookies is usually a working method to work out how to shortcut the - javascript need. - - In the actual
tag for the login, lots of sites fill-in random/session - or otherwise secretly generated hidden tags and you may need to first capture - the HTML code for the login form and extract all the hidden fields to be able - to do a proper login POST. Remember that the contents need to be URL encoded - when sent in a normal POST. - -13. Debug - - 13.1 Some debug tricks - - Many times when you run curl on a site, you'll notice that the site doesn't - seem to respond the same way to your curl requests as it does to your - browser's. - - Then you need to start making your curl requests more similar to your - browser's requests: - - * Use the --trace-ascii option to store fully detailed logs of the requests - for easier analyzing and better understanding - - * Make sure you check for and use cookies when needed (both reading with - --cookie and writing with --cookie-jar) - - * Set user-agent to one like a recent popular browser does - - * Set referer like it is set by the browser - - * If you use POST, make sure you send all the fields and in the same order as - the browser does it. - - A very good helper to make sure you do this right, is the LiveHTTPHeader tool - that lets you view all headers you send and receive with Mozilla/Firefox - (even when using HTTPS). Chrome features similar functionality out of the box - among the developer's tools. - - A more raw approach is to capture the HTTP traffic on the network with tools - such as ethereal or tcpdump and check what headers that were sent and - received by the browser. (HTTPS makes this technique inefficient.) - -14. References - - 14.1 Standards - - RFC 7230 is a must to read if you want in-depth understanding of the HTTP - protocol - - RFC 3986 explains the URL syntax - - RFC 1867 defines the HTTP post upload format - - RFC 6525 defines how HTTP cookies work - - 14.2 Sites - - https://curl.haxx.se is the home of the curl project diff --git a/extern/curl/docs/TheArtOfHttpScripting.md b/extern/curl/docs/TheArtOfHttpScripting.md new file mode 100644 index 0000000000..78dbd7a8f7 --- /dev/null +++ b/extern/curl/docs/TheArtOfHttpScripting.md @@ -0,0 +1,700 @@ +# The Art Of Scripting HTTP Requests Using Curl + +## Background + + This document assumes that you are familiar with HTML and general networking. + + The increasing amount of applications moving to the web has made "HTTP + Scripting" more frequently requested and wanted. To be able to automatically + extract information from the web, to fake users, to post or upload data to + web servers are all important tasks today. + + Curl is a command line tool for doing all sorts of URL manipulations and + transfers, but this particular document will focus on how to use it when + doing HTTP requests for fun and profit. I will assume that you know how to + invoke `curl --help` or `curl --manual` to get basic information about it. + + Curl is not written to do everything for you. It makes the requests, it gets + the data, it sends data and it retrieves the information. You probably need + to glue everything together using some kind of script language or repeated + manual invokes. + +## The HTTP Protocol + + HTTP is the protocol used to fetch data from web servers. It is a simple + protocol that is built upon TCP/IP. The protocol also allows information to + get sent to the server from the client using a few different methods, as will + be shown here. + + HTTP is plain ASCII text lines being sent by the client to a server to + request a particular action, and then the server replies a few text lines + before the actual requested content is sent to the client. + + The client, curl, sends an HTTP request. The request contains a method (like + GET, POST, HEAD etc), a number of request headers and sometimes a request + body. The HTTP server responds with a status line (indicating if things went + well), response headers and most often also a response body. The "body" part + is the plain data you requested, like the actual HTML or the image etc. + +## See the Protocol + + Using curl's option [`--verbose`](https://curl.se/docs/manpage.html#-v) + (`-v` as a short option) will display what kind of commands curl sends to the + server, as well as a few other informational texts. + + `--verbose` is the single most useful option when it comes to debug or even + understand the curl<->server interaction. + + Sometimes even `--verbose` is not enough. Then + [`--trace`](https://curl.se/docs/manpage.html#-trace) and + [`--trace-ascii`](https://curl.se/docs/manpage.html#--trace-ascii) + offer even more details as they show **everything** curl sends and + receives. Use it like this: + + curl --trace-ascii debugdump.txt http://www.example.com/ + +## See the Timing + + Many times you may wonder what exactly is taking all the time, or you just + want to know the amount of milliseconds between two points in a transfer. For + those, and other similar situations, the + [`--trace-time`](https://curl.se/docs/manpage.html#--trace-time) option + is what you need. It will prepend the time to each trace output line: + + curl --trace-ascii d.txt --trace-time http://example.com/ + +## See the Response + + By default curl sends the response to stdout. You need to redirect it + somewhere to avoid that, most often that is done with ` -o` or `-O`. + +# URL + +## Spec + + The Uniform Resource Locator format is how you specify the address of a + particular resource on the Internet. You know these, you have seen URLs like + https://curl.se or https://yourbank.com a million times. RFC 3986 is the + canonical spec. And yeah, the formal name is not URL, it is URI. + +## Host + + The host name is usually resolved using DNS or your /etc/hosts file to an IP + address and that is what curl will communicate with. Alternatively you specify + the IP address directly in the URL instead of a name. + + For development and other trying out situations, you can point to a different + IP address for a host name than what would otherwise be used, by using curl's + [`--resolve`](https://curl.se/docs/manpage.html#--resolve) option: + + curl --resolve www.example.org:80:127.0.0.1 http://www.example.org/ + +## Port number + + Each protocol curl supports operates on a default port number, be it over TCP + or in some cases UDP. Normally you do not have to take that into + consideration, but at times you run test servers on other ports or + similar. Then you can specify the port number in the URL with a colon and a + number immediately following the host name. Like when doing HTTP to port + 1234: + + curl http://www.example.org:1234/ + + The port number you specify in the URL is the number that the server uses to + offer its services. Sometimes you may use a proxy, and then you may + need to specify that proxy's port number separately from what curl needs to + connect to the server. Like when using an HTTP proxy on port 4321: + + curl --proxy http://proxy.example.org:4321 http://remote.example.org/ + +## User name and password + + Some services are setup to require HTTP authentication and then you need to + provide name and password which is then transferred to the remote site in + various ways depending on the exact authentication protocol used. + + You can opt to either insert the user and password in the URL or you can + provide them separately: + + curl http://user:password@example.org/ + + or + + curl -u user:password http://example.org/ + + You need to pay attention that this kind of HTTP authentication is not what + is usually done and requested by user-oriented websites these days. They tend + to use forms and cookies instead. + +## Path part + + The path part is just sent off to the server to request that it sends back + the associated response. The path is what is to the right side of the slash + that follows the host name and possibly port number. + +# Fetch a page + +## GET + + The simplest and most common request/operation made using HTTP is to GET a + URL. The URL could itself refer to a web page, an image or a file. The client + issues a GET request to the server and receives the document it asked for. + If you issue the command line + + curl https://curl.se + + you get a web page returned in your terminal window. The entire HTML document + that that URL holds. + + All HTTP replies contain a set of response headers that are normally hidden, + use curl's [`--include`](https://curl.se/docs/manpage.html#-i) (`-i`) + option to display them as well as the rest of the document. + +## HEAD + + You can ask the remote server for ONLY the headers by using the + [`--head`](https://curl.se/docs/manpage.html#-I) (`-I`) option which + will make curl issue a HEAD request. In some special cases servers deny the + HEAD method while others still work, which is a particular kind of annoyance. + + The HEAD method is defined and made so that the server returns the headers + exactly the way it would do for a GET, but without a body. It means that you + may see a `Content-Length:` in the response headers, but there must not be an + actual body in the HEAD response. + +## Multiple URLs in a single command line + + A single curl command line may involve one or many URLs. The most common case + is probably to just use one, but you can specify any amount of URLs. Yes + any. No limits. You will then get requests repeated over and over for all the + given URLs. + + Example, send two GETs: + + curl http://url1.example.com http://url2.example.com + + If you use [`--data`](https://curl.se/docs/manpage.html#-d) to POST to + the URL, using multiple URLs means that you send that same POST to all the + given URLs. + + Example, send two POSTs: + + curl --data name=curl http://url1.example.com http://url2.example.com + + +## Multiple HTTP methods in a single command line + + Sometimes you need to operate on several URLs in a single command line and do + different HTTP methods on each. For this, you will enjoy the + [`--next`](https://curl.se/docs/manpage.html#-:) option. It is basically + a separator that separates a bunch of options from the next. All the URLs + before `--next` will get the same method and will get all the POST data + merged into one. + + When curl reaches the `--next` on the command line, it will sort of reset the + method and the POST data and allow a new set. + + Perhaps this is best shown with a few examples. To send first a HEAD and then + a GET: + + curl -I http://example.com --next http://example.com + + To first send a POST and then a GET: + + curl -d score=10 http://example.com/post.cgi --next http://example.com/results.html + +# HTML forms + +## Forms explained + + Forms are the general way a website can present an HTML page with fields for + the user to enter data in, and then press some kind of 'OK' or 'Submit' + button to get that data sent to the server. The server then typically uses + the posted data to decide how to act. Like using the entered words to search + in a database, or to add the info in a bug tracking system, display the + entered address on a map or using the info as a login-prompt verifying that + the user is allowed to see what it is about to see. + + Of course there has to be some kind of program on the server end to receive + the data you send. You cannot just invent something out of the air. + +## GET + + A GET-form uses the method GET, as specified in HTML like: + +```html + + + +
+``` + + In your favorite browser, this form will appear with a text box to fill in + and a press-button labeled "OK". If you fill in '1905' and press the OK + button, your browser will then create a new URL to get for you. The URL will + get `junk.cgi?birthyear=1905&press=OK` appended to the path part of the + previous URL. + + If the original form was seen on the page `www.example.com/when/birth.html`, + the second page you will get will become + `www.example.com/when/junk.cgi?birthyear=1905&press=OK`. + + Most search engines work this way. + + To make curl do the GET form post for you, just enter the expected created + URL: + + curl "http://www.example.com/when/junk.cgi?birthyear=1905&press=OK" + +## POST + + The GET method makes all input field names get displayed in the URL field of + your browser. That is generally a good thing when you want to be able to + bookmark that page with your given data, but it is an obvious disadvantage if + you entered secret information in one of the fields or if there are a large + amount of fields creating a long and unreadable URL. + + The HTTP protocol then offers the POST method. This way the client sends the + data separated from the URL and thus you will not see any of it in the URL + address field. + + The form would look similar to the previous one: + +```html +
+ + +
+``` + + And to use curl to post this form with the same data filled in as before, we + could do it like: + + curl --data "birthyear=1905&press=%20OK%20" http://www.example.com/when/junk.cgi + + This kind of POST will use the Content-Type + `application/x-www-form-urlencoded` and is the most widely used POST kind. + + The data you send to the server MUST already be properly encoded, curl will + not do that for you. For example, if you want the data to contain a space, + you need to replace that space with `%20`, etc. Failing to comply with this will + most likely cause your data to be received wrongly and messed up. + + Recent curl versions can in fact url-encode POST data for you, like this: + + curl --data-urlencode "name=I am Daniel" http://www.example.com + + If you repeat `--data` several times on the command line, curl will + concatenate all the given data pieces - and put a `&` symbol between each + data segment. + +## File Upload POST + + Back in late 1995 they defined an additional way to post data over HTTP. It + is documented in the RFC 1867, why this method sometimes is referred to as + RFC1867-posting. + + This method is mainly designed to better support file uploads. A form that + allows a user to upload a file could be written like this in HTML: + +```html +
+ + +
+``` + + This clearly shows that the Content-Type about to be sent is + `multipart/form-data`. + + To post to a form like this with curl, you enter a command line like: + + curl --form upload=@localfilename --form press=OK [URL] + +## Hidden Fields + + A common way for HTML based applications to pass state information between + pages is to add hidden fields to the forms. Hidden fields are already filled + in, they are not displayed to the user and they get passed along just as all + the other fields. + + A similar example form with one visible field, one hidden field and one + submit button could look like: + +```html +
+ + + +
+``` + + To POST this with curl, you will not have to think about if the fields are + hidden or not. To curl they are all the same: + + curl --data "birthyear=1905&press=OK&person=daniel" [URL] + +## Figure Out What A POST Looks Like + + When you are about to fill in a form and send it to a server by using curl + instead of a browser, you are of course interested in sending a POST exactly + the way your browser does. + + An easy way to get to see this, is to save the HTML page with the form on + your local disk, modify the 'method' to a GET, and press the submit button + (you could also change the action URL if you want to). + + You will then clearly see the data get appended to the URL, separated with a + `?`-letter as GET forms are supposed to. + +# HTTP upload + +## PUT + + Perhaps the best way to upload data to an HTTP server is to use PUT. Then + again, this of course requires that someone put a program or script on the + server end that knows how to receive an HTTP PUT stream. + + Put a file to an HTTP server with curl: + + curl --upload-file uploadfile http://www.example.com/receive.cgi + +# HTTP Authentication + +## Basic Authentication + + HTTP Authentication is the ability to tell the server your username and + password so that it can verify that you are allowed to do the request you are + doing. The Basic authentication used in HTTP (which is the type curl uses by + default) is **plain text** based, which means it sends username and password + only slightly obfuscated, but still fully readable by anyone that sniffs on + the network between you and the remote server. + + To tell curl to use a user and password for authentication: + + curl --user name:password http://www.example.com + +## Other Authentication + + The site might require a different authentication method (check the headers + returned by the server), and then + [`--ntlm`](https://curl.se/docs/manpage.html#--ntlm), + [`--digest`](https://curl.se/docs/manpage.html#--digest), + [`--negotiate`](https://curl.se/docs/manpage.html#--negotiate) or even + [`--anyauth`](https://curl.se/docs/manpage.html#--anyauth) might be + options that suit you. + +## Proxy Authentication + + Sometimes your HTTP access is only available through the use of an HTTP + proxy. This seems to be especially common at various companies. An HTTP proxy + may require its own user and password to allow the client to get through to + the Internet. To specify those with curl, run something like: + + curl --proxy-user proxyuser:proxypassword curl.se + + If your proxy requires the authentication to be done using the NTLM method, + use [`--proxy-ntlm`](https://curl.se/docs/manpage.html#--proxy-ntlm), if + it requires Digest use + [`--proxy-digest`](https://curl.se/docs/manpage.html#--proxy-digest). + + If you use any one of these user+password options but leave out the password + part, curl will prompt for the password interactively. + +## Hiding credentials + + Do note that when a program is run, its parameters might be possible to see + when listing the running processes of the system. Thus, other users may be + able to watch your passwords if you pass them as plain command line + options. There are ways to circumvent this. + + It is worth noting that while this is how HTTP Authentication works, many + websites will not use this concept when they provide logins etc. See the Web + Login chapter further below for more details on that. + +# More HTTP Headers + +## Referer + + An HTTP request may include a 'referer' field (yes it is misspelled), which + can be used to tell from which URL the client got to this particular + resource. Some programs/scripts check the referer field of requests to verify + that this was not arriving from an external site or an unknown page. While + this is a stupid way to check something so easily forged, many scripts still + do it. Using curl, you can put anything you want in the referer-field and + thus more easily be able to fool the server into serving your request. + + Use curl to set the referer field with: + + curl --referer http://www.example.come http://www.example.com + +## User Agent + + Similar to the referer field, all HTTP requests may set the User-Agent + field. It names what user agent (client) that is being used. Many + applications use this information to decide how to display pages. Silly web + programmers try to make different pages for users of different browsers to + make them look the best possible for their particular browsers. They usually + also do different kinds of JavaScript, VBScript etc. + + At times, you will see that getting a page with curl will not return the same + page that you see when getting the page with your browser. Then you know it + is time to set the User Agent field to fool the server into thinking you are + one of those browsers. + + To make curl look like Internet Explorer 5 on a Windows 2000 box: + + curl --user-agent "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" [URL] + + Or why not look like you are using Netscape 4.73 on an old Linux box: + + curl --user-agent "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" [URL] + +## Redirects + +## Location header + + When a resource is requested from a server, the reply from the server may + include a hint about where the browser should go next to find this page, or a + new page keeping newly generated output. The header that tells the browser to + redirect is `Location:`. + + Curl does not follow `Location:` headers by default, but will simply display + such pages in the same manner it displays all HTTP replies. It does however + feature an option that will make it attempt to follow the `Location:` + pointers. + + To tell curl to follow a Location: + + curl --location http://www.example.com + + If you use curl to POST to a site that immediately redirects you to another + page, you can safely use + [`--location`](https://curl.se/docs/manpage.html#-L) (`-L`) and + `--data`/`--form` together. Curl will only use POST in the first request, and + then revert to GET in the following operations. + +## Other redirects + + Browsers typically support at least two other ways of redirects that curl + does not: first the html may contain a meta refresh tag that asks the browser + to load a specific URL after a set number of seconds, or it may use + JavaScript to do it. + +# Cookies + +## Cookie Basics + + The way the web browsers do "client side state control" is by using + cookies. Cookies are just names with associated contents. The cookies are + sent to the client by the server. The server tells the client for what path + and host name it wants the cookie sent back, and it also sends an expiration + date and a few more properties. + + When a client communicates with a server with a name and path as previously + specified in a received cookie, the client sends back the cookies and their + contents to the server, unless of course they are expired. + + Many applications and servers use this method to connect a series of requests + into a single logical session. To be able to use curl in such occasions, we + must be able to record and send back cookies the way the web application + expects them. The same way browsers deal with them. + +## Cookie options + + The simplest way to send a few cookies to the server when getting a page with + curl is to add them on the command line like: + + curl --cookie "name=Daniel" http://www.example.com + + Cookies are sent as common HTTP headers. This is practical as it allows curl + to record cookies simply by recording headers. Record cookies with curl by + using the [`--dump-header`](https://curl.se/docs/manpage.html#-D) (`-D`) + option like: + + curl --dump-header headers_and_cookies http://www.example.com + + (Take note that the + [`--cookie-jar`](https://curl.se/docs/manpage.html#-c) option described + below is a better way to store cookies.) + + Curl has a full blown cookie parsing engine built-in that comes in use if you + want to reconnect to a server and use cookies that were stored from a + previous connection (or hand-crafted manually to fool the server into + believing you had a previous connection). To use previously stored cookies, + you run curl like: + + curl --cookie stored_cookies_in_file http://www.example.com + + Curl's "cookie engine" gets enabled when you use the + [`--cookie`](https://curl.se/docs/manpage.html#-b) option. If you only + want curl to understand received cookies, use `--cookie` with a file that + does not exist. Example, if you want to let curl understand cookies from a + page and follow a location (and thus possibly send back cookies it received), + you can invoke it like: + + curl --cookie nada --location http://www.example.com + + Curl has the ability to read and write cookie files that use the same file + format that Netscape and Mozilla once used. It is a convenient way to share + cookies between scripts or invokes. The `--cookie` (`-b`) switch + automatically detects if a given file is such a cookie file and parses it, + and by using the `--cookie-jar` (`-c`) option you will make curl write a new + cookie file at the end of an operation: + + curl --cookie cookies.txt --cookie-jar newcookies.txt \ + http://www.example.com + +# HTTPS + +## HTTPS is HTTP secure + + There are a few ways to do secure HTTP transfers. By far the most common + protocol for doing this is what is generally known as HTTPS, HTTP over + SSL. SSL encrypts all the data that is sent and received over the network and + thus makes it harder for attackers to spy on sensitive information. + + SSL (or TLS as the latest version of the standard is called) offers a + truckload of advanced features to allow all those encryptions and key + infrastructure mechanisms encrypted HTTP requires. + + Curl supports encrypted fetches when built to use a TLS library and it can be + built to use one out of a fairly large set of libraries - `curl -V` will show + which one your curl was built to use (if any!). To get a page from an HTTPS + server, simply run curl like: + + curl https://secure.example.com + +## Certificates + + In the HTTPS world, you use certificates to validate that you are the one + you claim to be, as an addition to normal passwords. Curl supports client- + side certificates. All certificates are locked with a pass phrase, which you + need to enter before the certificate can be used by curl. The pass phrase + can be specified on the command line or if not, entered interactively when + curl queries for it. Use a certificate with curl on an HTTPS server like: + + curl --cert mycert.pem https://secure.example.com + + curl also tries to verify that the server is who it claims to be, by + verifying the server's certificate against a locally stored CA cert + bundle. Failing the verification will cause curl to deny the connection. You + must then use [`--insecure`](https://curl.se/docs/manpage.html#-k) + (`-k`) in case you want to tell curl to ignore that the server cannot be + verified. + + More about server certificate verification and ca cert bundles can be read in + the [SSLCERTS document](https://curl.se/docs/sslcerts.html). + + At times you may end up with your own CA cert store and then you can tell + curl to use that to verify the server's certificate: + + curl --cacert ca-bundle.pem https://example.com/ + +# Custom Request Elements + +## Modify method and headers + + Doing fancy stuff, you may need to add or change elements of a single curl + request. + + For example, you can change the POST request to a PROPFIND and send the data + as `Content-Type: text/xml` (instead of the default Content-Type) like this: + + curl --data "" --header "Content-Type: text/xml" \ + --request PROPFIND example.com + + You can delete a default header by providing one without content. Like you + can ruin the request by chopping off the Host: header: + + curl --header "Host:" http://www.example.com + + You can add headers the same way. Your server may want a `Destination:` + header, and you can add it: + + curl --header "Destination: http://nowhere" http://example.com + +## More on changed methods + + It should be noted that curl selects which methods to use on its own + depending on what action to ask for. `-d` will do POST, `-I` will do HEAD and + so on. If you use the + [`--request`](https://curl.se/docs/manpage.html#-X) / `-X` option you + can change the method keyword curl selects, but you will not modify curl's + behavior. This means that if you for example use -d "data" to do a POST, you + can modify the method to a `PROPFIND` with `-X` and curl will still think it + sends a POST . You can change the normal GET to a POST method by simply + adding `-X POST` in a command line like: + + curl -X POST http://example.org/ + + ... but curl will still think and act as if it sent a GET so it will not send + any request body etc. + +# Web Login + +## Some login tricks + + While not strictly just HTTP related, it still causes a lot of people + problems so here's the executive run-down of how the vast majority of all + login forms work and how to login to them using curl. + + It can also be noted that to do this properly in an automated fashion, you + will most certainly need to script things and do multiple curl invokes etc. + + First, servers mostly use cookies to track the logged-in status of the + client, so you will need to capture the cookies you receive in the + responses. Then, many sites also set a special cookie on the login page (to + make sure you got there through their login page) so you should make a habit + of first getting the login-form page to capture the cookies set there. + + Some web-based login systems feature various amounts of JavaScript, and + sometimes they use such code to set or modify cookie contents. Possibly they + do that to prevent programmed logins, like this manual describes how to... + Anyway, if reading the code is not enough to let you repeat the behavior + manually, capturing the HTTP requests done by your browsers and analyzing the + sent cookies is usually a working method to work out how to shortcut the + JavaScript need. + + In the actual `
` tag for the login, lots of sites fill-in + random/session or otherwise secretly generated hidden tags and you may need + to first capture the HTML code for the login form and extract all the hidden + fields to be able to do a proper login POST. Remember that the contents need + to be URL encoded when sent in a normal POST. + +# Debug + +## Some debug tricks + + Many times when you run curl on a site, you will notice that the site does not + seem to respond the same way to your curl requests as it does to your + browser's. + + Then you need to start making your curl requests more similar to your + browser's requests: + + - Use the `--trace-ascii` option to store fully detailed logs of the requests + for easier analyzing and better understanding + + - Make sure you check for and use cookies when needed (both reading with + `--cookie` and writing with `--cookie-jar`) + + - Set user-agent (with [`-A`](https://curl.se/docs/manpage.html#-A)) to + one like a recent popular browser does + + - Set referer (with [`-E`](https://curl.se/docs/manpage.html#-E)) like + it is set by the browser + + - If you use POST, make sure you send all the fields and in the same order as + the browser does it. + +## Check what the browsers do + + A good helper to make sure you do this right, is the web browsers' developers + tools that let you view all headers you send and receive (even when using + HTTPS). + + A more raw approach is to capture the HTTP traffic on the network with tools + such as Wireshark or tcpdump and check what headers that were sent and + received by the browser. (HTTPS forces you to use `SSLKEYLOGFILE` to do + that.) diff --git a/extern/curl/docs/URL-SYNTAX.md b/extern/curl/docs/URL-SYNTAX.md new file mode 100644 index 0000000000..0b452f87fb --- /dev/null +++ b/extern/curl/docs/URL-SYNTAX.md @@ -0,0 +1,388 @@ +# URL syntax and their use in curl + +## Specifications + +The official "URL syntax" is primarily defined in these two different +specifications: + + - [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) (although URL is called + "URI" in there) + - [The WHATWG URL Specification](https://url.spec.whatwg.org/) + +RFC 3986 is the earlier one, and curl has always tried to adhere to that one +(since it shipped in January 2005). + +The WHATWG URL spec was written later, is incompatible with the RFC 3986 and +changes over time. + +## Variations + +URL parsers as implemented in browsers, libraries and tools usually opt to +support one of the mentioned specifications. Bugs, differences in +interpretations and the moving nature of the WHATWG spec does however make it +unlikely that multiple parsers treat URLs the same way. + +## Security + +Due to the inherent differences between URL parser implementations, it is +considered a security risk to mix different implementations and assume the +same behavior! + +For example, if you use one parser to check if a URL uses a good host name or +the correct auth field, and then pass on that same URL to a *second* parser, +there will always be a risk it treats the same URL differently. There is no +right and wrong in URL land, only differences of opinions. + +libcurl offers a separate API to its URL parser for this reason, among others. + +Applications may at times find it convenient to allow users to specify URLs +for various purposes and that string would then end up fed to curl. Getting a +URL from an external untrusted party and using it with curl brings several +security concerns: + +1. If you have an application that runs as or in a server application, getting + an unfiltered URL can trick your application to access a local resource + instead of a remote resource. Protecting yourself against localhost accesses + is hard when accepting user provided URLs. + +2. Such custom URLs can access other ports than you planned as port numbers + are part of the regular URL format. The combination of a local host and a + custom port number can allow external users to play tricks with your local + services. + +3. Such a URL might use other schemes than you thought of or planned for. + +## "RFC3986 plus" + +curl recognizes a URL syntax that we call "RFC 3986 plus". It is grounded on +the well established RFC 3986 to make sure previously written command lines and +curl using scripts will remain working. + +curl's URL parser allows a few deviations from the spec in order to +inter-operate better with URLs that appear in the wild. + +### spaces + +A URL provided to curl cannot contain spaces. They need to be provided URL +encoded to be accepted in a URL by curl. + +An exception to this rule: `Location:` response headers that indicate to a +client where a resource has been redirected to, sometimes contain spaces. This +is a violation of RFC 3986 but is fine in the WHATWG spec. curl handles these +by re-encoding them to `%20`. + +### non-ASCII + +Byte values in a provided URL that are outside of the printable ASCII range +are percent-encoded by curl. + +### multiple slashes + +An absolute URL always starts with a "scheme" followed by a colon. For all the +schemes curl supports, the colon must be followed by two slashes according to +RFC 3986 but not according to the WHATWG spec - which allows one to infinity +amount. + +curl allows one, two or three slashes after the colon to still be considered a +valid URL. + +### "scheme-less" + +curl supports "URLs" that do not start with a scheme. This is not supported by +any of the specifications. This is a shortcut to entering URLs that was +supported by browsers early on and has been mimicked by curl. + +Based on what the host name starts with, curl will "guess" what protocol to +use: + + - `ftp.` means FTP + - `dict.` means DICT + - `ldap.` means LDAP + - `imap.` means IMAP + - `smtp.` means SMTP + - `pop3.` means POP3 + - all other means HTTP + +### globbing letters + +The curl command line tool supports "globbing" of URLs. It means that you can +create ranges and lists using `[N-M]` and `{one,two,three}` sequences. The +letters used for this (`[]{}`) are reserved in RFC 3986 and can therefore not +legitimately be part of such a URL. + +They are however not reserved or special in the WHATWG specification, so +globbing can mess up such URLs. Globbing can be turned off for such occasions +(using `--globoff`). + +# URL syntax details + +A URL may consist of the following components - many of them are optional: + + [scheme][divider][userinfo][hostname][port number][path][query][fragment] + +Each component is separated from the following component with a divider +character or string. + +For example, this could look like: + + http://user:password@www.example.com:80/index.hmtl?foo=bar#top + +## Scheme + +The scheme specifies the protocol to use. A curl build can support a few or +many different schemes. You can limit what schemes curl should accept. + +curl supports the following schemes on URLs specified to transfer. They are +matched case insensitively: + +`dict`, `file`, `ftp`, `ftps`, `gopher`, `gophers`, `http`, `https`, `imap`, +`imaps`, `ldap`, `ldaps`, `mqtt`, `pop3`, `pop3s`, `rtmp`, `rtmpe`, `rtmps`, +`rtmpt`, `rtmpte`, `rtmpts`, `rtsp`, `smb`, `smbs`, `smtp`, `smtps`, `telnet`, +`tftp` + +When the URL is specified to identify a proxy, curl recognizes the following +schemes: + +`http`, `https`, `socks4`, `socks4a`, `socks5`, `socks5h`, `socks` + +## Userinfo + +The userinfo field can be used to set user name and password for +authentication purposes in this transfer. The use of this field is discouraged +since it often means passing around the password in plain text and is thus a +security risk. + +URLs for IMAP, POP3 and SMTP also support *login options* as part of the +userinfo field. They are provided as a semicolon after the password and then +the options. + +## Hostname + +The hostname part of the URL contains the address of the server that you want +to connect to. This can be the fully qualified domain name of the server, the +local network name of the machine on your network or the IP address of the +server or machine represented by either an IPv4 or IPv6 address (within +brackets). For example: + + http://www.example.com/ + + http://hostname/ + + http://192.168.0.1/ + + http://[2001:1890:1112:1::20]/ + +### "localhost" + +Starting in curl 7.77.0, curl uses loopback IP addresses for the name +`localhost`: `127.0.0.1` and `::1`. It does not resolve the name using the +resolver functions. + +This is done to make sure the host accessed is truly the localhost - the local +machine. + +### IDNA + +If curl was built with International Domain Name (IDN) support, it can also +handle host names using non-ASCII characters. + +When built with libidn2, curl uses the IDNA 2008 standard. This is equivalent +to the WHATWG URL spec, but differs from certain browsers that use IDNA 2003 +Transitional Processing. The two standards have a huge overlap but differ +slightly, perhaps most famously in how they deal with the German "double s" +(`ß`). + +When winidn is used, curl uses IDNA 2003 Transitional Processing, like the rest +of Windows. + +## Port number + +If there's a colon after the hostname, that should be followed by the port +number to use. 1 - 65535. curl also supports a blank port number field - but +only if the URL starts with a scheme. + +If the port number is not specified in the URL, curl will used a default port +based on the provide scheme: + +DICT 2628, FTP 21, FTPS 990, GOPHER 70, GOPHERS 70, HTTP 80, HTTPS 443, +IMAP 132, IMAPS 993, LDAP 369, LDAPS 636, MQTT 1883, POP3 110, POP3S 995, +RTMP 1935, RTMPS 443, RTMPT 80, RTSP 554, SCP 22, SFTP 22, SMB 445, SMBS 445, +SMTP 25, SMTPS 465, TELNET 23, TFTP 69 + +# Scheme specific behaviors + +## FTP + +The path part of an FTP request specifies the file to retrieve and from which +directory. If the file part is omitted then libcurl downloads the directory +listing for the directory specified. If the directory is omitted then the +directory listing for the root / home directory will be returned. + +FTP servers typically put the user in its "home directory" after login, which +then differs between users. To explicitly specify the root directory of an FTP +server, start the path with double slash `//` or `/%2f` (2F is the hexadecimal +value of the ascii code for the slash). + +## FILE + +When a `FILE://` URL is accessed on Windows systems, it can be crafted in a +way so that Windows attempts to connect to a (remote) machine when curl wants +to read or write such a path. + +curl only allows the hostname part of a FILE URL to be one out of these three +alternatives: `localhost`, `127.0.0.1` or blank ("", zero characters). +Anything else will make curl fail to parse the URL. + +### Windows-specific FILE details + +curl accepts that the FILE URL's path starts with a "drive letter". That is a +single letter `a` to `z` followed by a colon or a pipe character (`|`). + +The Windows operating system itself will convert some file accesses to perform +network accesses over SMB/CIFS, through several different file path patterns. +This way, a `file://` URL passed to curl *might* be converted into a network +access inadvertently and unknowingly to curl. This is a Windows feature curl +cannot control or disable. + +## IMAP + +The path part of an IMAP request not only specifies the mailbox to list or +select, but can also be used to check the `UIDVALIDITY` of the mailbox, to +specify the `UID`, `SECTION` and `PARTIAL` octets of the message to fetch and +to specify what messages to search for. + +A top level folder list: + + imap://user:password@mail.example.com + +A folder list on the user's inbox: + + imap://user:password@mail.example.com/INBOX + +Select the user's inbox and fetch message with uid = 1: + + imap://user:password@mail.example.com/INBOX/;UID=1 + +Select the user's inbox and fetch the first message in the mail box: + + imap://user:password@mail.example.com/INBOX/;MAILINDEX=1 + +Select the user's inbox, check the `UIDVALIDITY` of the mailbox is 50 and +fetch message 2 if it is: + + imap://user:password@mail.example.com/INBOX;UIDVALIDITY=50/;UID=2 + +Select the user's inbox and fetch the text portion of message 3: + + imap://user:password@mail.example.com/INBOX/;UID=3/;SECTION=TEXT + +Select the user's inbox and fetch the first 1024 octets of message 4: + + imap://user:password@mail.example.com/INBOX/;UID=4/;PARTIAL=0.1024 + +Select the user's inbox and check for NEW messages: + + imap://user:password@mail.example.com/INBOX?NEW + +Select the user's inbox and search for messages containing "shadows" in the +subject line: + + imap://user:password@mail.example.com/INBOX?SUBJECT%20shadows + +Searching via the query part of the URL `?` is a search request for the results +to be returned as message sequence numbers (MAILINDEX). It is possible to make +a search request for results to be returned as unique ID numbers (UID) by using +a custom curl request via `-X`. UID numbers are unique per session (and +multiple sessions when UIDVALIDITY is the same). For example, if you are +searching for `"foo bar"` in header+body (TEXT) and you want the matching +MAILINDEX numbers returned then you could search via URL: + + imap://user:password@mail.example.com/INBOX?TEXT%20%22foo%20bar%22 + +.. but if you wanted matching UID numbers you would have to use a custom request: + + imap://user:password@mail.example.com/INBOX -X "UID SEARCH TEXT \"foo bar\"" + +For more information about IMAP commands please see RFC 9051. For more +information about the individual components of an IMAP URL please see RFC 5092. + +* Note old curl versions would FETCH by message sequence number when UID was +specified in the URL. That was a bug fixed in 7.62.0, which added MAILINDEX to +FETCH by mail sequence number. + +## LDAP + +The path part of a LDAP request can be used to specify the: Distinguished +Name, Attributes, Scope, Filter and Extension for a LDAP search. Each field is +separated by a question mark and when that field is not required an empty +string with the question mark separator should be included. + +Search for the DN as `My Organization`: + + ldap://ldap.example.com/o=My%20Organization + +the same search but will only return postalAddress attributes: + + ldap://ldap.example.com/o=My%20Organization?postalAddress + +Search for an empty DN and request information about the +`rootDomainNamingContext` attribute for an Active Directory server: + + ldap://ldap.example.com/?rootDomainNamingContext + +For more information about the individual components of a LDAP URL please +see [RFC 4516](https://datatracker.ietf.org/doc/html/rfc4516). + +## POP3 + +The path part of a POP3 request specifies the message ID to retrieve. If the +ID is not specified then a list of waiting messages is returned instead. + +## SCP + +The path part of an SCP URL specifies the path and file to retrieve or +upload. The file is taken as an absolute path from the root directory on the +server. + +To specify a path relative to the user's home directory on the server, prepend +`~/` to the path portion. + +## SFTP + +The path part of an SFTP URL specifies the file to retrieve or upload. If the +path ends with a slash (`/`) then a directory listing is returned instead of a +file. If the path is omitted entirely then the directory listing for the root +/ home directory will be returned. + +## SMB +The path part of a SMB request specifies the file to retrieve and from what +share and directory or the share to upload to and as such, may not be omitted. +If the user name is embedded in the URL then it must contain the domain name +and as such, the backslash must be URL encoded as %2f. + +curl supports SMB version 1 (only) + +## SMTP + +The path part of a SMTP request specifies the host name to present during +communication with the mail server. If the path is omitted, then libcurl will +attempt to resolve the local computer's host name. However, this may not +return the fully qualified domain name that is required by some mail servers +and specifying this path allows you to set an alternative name, such as your +machine's fully qualified domain name, which you might have obtained from an +external function such as gethostname or getaddrinfo. + +The default smtp port is 25. Some servers use port 587 as an alternative. + +## RTMP + +There's no official URL spec for RTMP so libcurl uses the URL syntax supported +by the underlying librtmp library. It has a syntax where it wants a +traditional URL, followed by a space and a series of space-separated +`name=value` pairs. + +While space is not typically a "legal" letter, libcurl accepts them. When a +user wants to pass in a `#` (hash) character it will be treated as a fragment +and get cut off by libcurl if provided literally. You will instead have to +escape it by providing it as backslash and its ASCII value in hexadecimal: +`\23`. diff --git a/extern/curl/docs/VERSIONS b/extern/curl/docs/VERSIONS.md similarity index 76% rename from extern/curl/docs/VERSIONS rename to extern/curl/docs/VERSIONS.md index 72a45474de..de0b0d4f85 100644 --- a/extern/curl/docs/VERSIONS +++ b/extern/curl/docs/VERSIONS.md @@ -1,8 +1,8 @@ Version Numbers and Releases ============================ - Curl is not only curl. Curl is also libcurl. They're actually individually - versioned, but they mostly follow each other rather closely. + Curl is not only curl. Curl is also libcurl. they are actually individually + versioned, but they usually follow each other closely. The version numbering is always built up using the same system: @@ -15,22 +15,21 @@ Version Numbers and Releases ## Bumping numbers One of these numbers will get bumped in each new release. The numbers to the - right of a bumped number will be reset to zero. If Z is zero, it may not be - included in the version number. + right of a bumped number will be reset to zero. The main version number will get bumped when *really* big, world colliding changes are made. The release number is bumped when changes are performed or things/features are added. The patch number is bumped when the changes are mere bugfixes. - It means that after release 1.2.3, we can release 2.0 if something really big - has been made, 1.3 if not that big changes were made or 1.2.4 if mostly bugs - were fixed. + It means that after release 1.2.3, we can release 2.0.0 if something really + big has been made, 1.3.0 if not that big changes were made or 1.2.4 if only + bugs were fixed. Bumping, as in increasing the number with 1, is unconditionally only affecting one of the numbers (except the ones to the right of it, that may be set to zero). 1 becomes 2, 3 becomes 4, 9 becomes 10, 88 becomes 89 and 99 - becomes 100. So, after 1.2.9 comes 1.2.10. After 3.99.3, 3.100 might come. + becomes 100. So, after 1.2.9 comes 1.2.10. After 3.99.3, 3.100.0 might come. All original curl source release archives are named according to the libcurl version (not according to the curl client version that, as said before, might @@ -42,7 +41,9 @@ Version Numbers and Releases numbering scheme that can be used for comparison. The version number is defined as: - #define LIBCURL_VERSION_NUM 0xXXYYZZ +```c +#define LIBCURL_VERSION_NUM 0xXXYYZZ +``` Where XX, YY and ZZ are the main version, release and patch numbers in hexadecimal. All three number fields are always represented using two digits diff --git a/extern/curl/docs/cmdline-opts/CMakeLists.txt b/extern/curl/docs/cmdline-opts/CMakeLists.txt index 3c020d418d..ae25c5c4ac 100644 --- a/extern/curl/docs/cmdline-opts/CMakeLists.txt +++ b/extern/curl/docs/cmdline-opts/CMakeLists.txt @@ -1,3 +1,24 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### set(MANPAGE "${CURL_BINARY_DIR}/docs/curl.1") # Load DPAGES and OTHERPAGES from shared file diff --git a/extern/curl/docs/cmdline-opts/MANPAGE.md b/extern/curl/docs/cmdline-opts/MANPAGE.md index 3a8270b03e..e3f5681a2f 100644 --- a/extern/curl/docs/cmdline-opts/MANPAGE.md +++ b/extern/curl/docs/cmdline-opts/MANPAGE.md @@ -3,7 +3,8 @@ This is the curl man page generator. It generates a single nroff man page output from the set of sources files in this directory. -There is one source file for each supported command line option. The format is +There is one source file for each supported command line option. The output +gets `page-header` prepended and `page-footer` appended. The format is described below. ## Option files @@ -27,18 +28,27 @@ Each file has a set of meta-data and a body of text. Requires: (space separated list of features this requires, no dashes) See-also: (space separated list of related options, no dashes) Help: (short text for the --help output for this option) + Example: (example command line, without "curl" and can use `$URL`) --- (end of meta-data) ### Body The body of the description. Only refer to options with their long form option -version, like --verbose. The output generator will replace such with the +version, like `--verbose`. The output generator will replace such with the correct markup that shows both short and long version. -## Header +Text written within `*asterisks*` will get shown using italics. Text within +two `**asterisks**` will get shown using bold. -`page-header` is the nroff formatted file that will be output before the -generated options output for the master man page. +Text that is prefixed with a space will be treated like an "example" and will +be output in monospace. + +## Header and footer + +`page-header` is the file that will be output before the generated options +output for the master man page. + +`page-footer` is appended after all the individual options. ## Generate diff --git a/extern/curl/docs/cmdline-opts/Makefile.am b/extern/curl/docs/cmdline-opts/Makefile.am index e6ecf7a6b0..f416d553e3 100644 --- a/extern/curl/docs/cmdline-opts/Makefile.am +++ b/extern/curl/docs/cmdline-opts/Makefile.am @@ -5,11 +5,11 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. +# Copyright (C) 1998 - 2020, Daniel Stenberg, , et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms -# are also available at https://curl.haxx.se/docs/copyright.html. +# are also available at https://curl.se/docs/copyright.html. # # You may opt to use, copy, modify, merge, publish, distribute and/or sell # copies of the Software, and permit persons to whom the Software is @@ -31,4 +31,5 @@ EXTRA_DIST = $(DPAGES) MANPAGE.md gen.pl $(OTHERPAGES) CMakeLists.txt all: $(MANPAGE) $(MANPAGE): $(DPAGES) $(OTHERPAGES) Makefile.inc - @PERL@ $(srcdir)/gen.pl mainpage $(srcdir) > $(MANPAGE) + @echo "generate $(MANPAGE)" + @(cd $(srcdir) && @PERL@ ./gen.pl mainpage $(DPAGES)) > $(MANPAGE) diff --git a/extern/curl/docs/cmdline-opts/Makefile.inc b/extern/curl/docs/cmdline-opts/Makefile.inc index 829551ff62..87819e087b 100644 --- a/extern/curl/docs/cmdline-opts/Makefile.inc +++ b/extern/curl/docs/cmdline-opts/Makefile.inc @@ -1,215 +1,273 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2022, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### # Shared between Makefile.am and CMakeLists.txt -DPAGES = \ - abstract-unix-socket.d \ - alt-svc.d \ - anyauth.d \ - append.d basic.d \ - cacert.d capath.d \ - cert-status.d \ - cert-type.d \ - cert.d \ - ciphers.d \ - compressed-ssh.d \ - compressed.d \ - config.d \ - connect-timeout.d \ - connect-to.d \ - continue-at.d \ - cookie-jar.d \ - cookie.d \ - create-dirs.d \ - crlf.d crlfile.d \ - data-ascii.d \ - data-binary.d \ - data-urlencode.d \ - data.d data-raw.d \ - delegation.d \ - digest.d \ - disable-eprt.d \ - disable-epsv.d \ - disable.d \ - disallow-username-in-url.d \ - dns-interface.d \ - dns-ipv4-addr.d \ - dns-ipv6-addr.d \ - dns-servers.d \ - doh-url.d \ - dump-header.d \ - egd-file.d \ - engine.d \ - etag-save.d \ - etag-compare.d \ - expect100-timeout.d \ - fail-early.d \ - fail.d \ - false-start.d \ - form-string.d \ - form.d \ - ftp-account.d \ - ftp-alternative-to-user.d \ - ftp-create-dirs.d \ - ftp-method.d \ - ftp-pasv.d \ - ftp-port.d \ - ftp-pret.d \ - ftp-skip-pasv-ip.d \ - ftp-ssl-ccc-mode.d \ - ftp-ssl-ccc.d \ - ftp-ssl-control.d \ - get.d globoff.d \ - happy-eyeballs-timeout-ms.d \ - haproxy-protocol.d \ - head.d header.d \ - help.d \ - hostpubmd5.d \ - http0.9.d \ - http1.0.d \ - http1.1.d http2.d \ - http2-prior-knowledge.d \ - http3.d \ - ignore-content-length.d \ - include.d \ - insecure.d \ - interface.d \ - ipv4.d ipv6.d \ - junk-session-cookies.d \ - keepalive-time.d \ - key.d key-type.d \ - krb.d libcurl.d \ - limit-rate.d \ - list-only.d \ - local-port.d \ - location-trusted.d \ - location.d \ - login-options.d \ - mail-auth.d \ - mail-from.d \ - mail-rcpt.d \ - manual.d \ - max-filesize.d \ - max-redirs.d \ - max-time.d \ - metalink.d \ - negotiate.d \ - netrc-file.d \ - netrc-optional.d \ - netrc.d \ - next.d no-alpn.d \ - no-buffer.d \ - no-keepalive.d \ - no-npn.d \ - no-progress-meter.d \ - no-sessionid.d \ - noproxy.d \ - ntlm.d ntlm-wb.d \ - oauth2-bearer.d \ - output.d \ - parallel-immediate.d \ - parallel-max.d \ - parallel.d \ - pass.d \ - path-as-is.d \ - pinnedpubkey.d \ - post301.d \ - post302.d \ - post303.d \ - preproxy.d \ - progress-bar.d \ - proto-default.d \ - proto-redir.d \ - proto.d \ - proxy-anyauth.d \ - proxy-basic.d \ - proxy-cacert.d \ - proxy-capath.d \ - proxy-cert-type.d \ - proxy-cert.d \ - proxy-ciphers.d \ - proxy-crlfile.d \ - proxy-digest.d \ - proxy-header.d \ - proxy-insecure.d \ - proxy-key-type.d \ - proxy-key.d \ - proxy-negotiate.d \ - proxy-ntlm.d \ - proxy-pass.d \ - proxy-pinnedpubkey.d \ - proxy-service-name.d \ - proxy-ssl-allow-beast.d \ - proxy-tls13-ciphers.d \ - proxy-tlsauthtype.d \ - proxy-tlspassword.d \ - proxy-tlsuser.d \ - proxy-tlsv1.d \ - proxy-user.d \ - proxy.d \ - proxy1.0.d \ - proxytunnel.d \ - pubkey.d quote.d \ - random-file.d \ - range.d raw.d \ - referer.d \ - remote-header-name.d \ - remote-name-all.d \ - remote-name.d \ - remote-time.d \ - request-target.d \ - request.d \ - resolve.d \ - retry-connrefused.d \ - retry-delay.d \ - retry-max-time.d \ - retry.d \ - sasl-authzid.d \ - sasl-ir.d \ - service-name.d \ - show-error.d \ - silent.d \ - socks4.d socks5.d \ - socks4a.d \ - socks5-basic.d \ - socks5-gssapi-nec.d \ - socks5-gssapi-service.d \ - socks5-gssapi.d \ - socks5-hostname.d \ - speed-limit.d \ - speed-time.d \ - ssl-allow-beast.d \ - ssl-no-revoke.d \ - ssl-reqd.d \ - ssl.d \ - sslv2.d sslv3.d \ - stderr.d \ - styled-output.d \ - suppress-connect-headers.d \ - tcp-fastopen.d \ - tcp-nodelay.d \ - telnet-option.d \ - tftp-blksize.d \ - tftp-no-options.d \ - time-cond.d \ - tls-max.d \ - tls13-ciphers.d \ - tlsauthtype.d \ - tlspassword.d \ - tlsuser.d \ - tlsv1.0.d \ - tlsv1.1.d \ - tlsv1.2.d \ - tlsv1.3.d tlsv1.d \ - tr-encoding.d \ - trace-ascii.d \ - trace-time.d \ - trace.d \ - unix-socket.d \ - upload-file.d \ - url.d use-ascii.d \ - user-agent.d \ - user.d verbose.d \ - version.d \ - write-out.d \ +DPAGES = \ + abstract-unix-socket.d \ + alt-svc.d \ + anyauth.d \ + append.d \ + aws-sigv4.d \ + basic.d \ + cacert.d \ + capath.d \ + cert-status.d \ + cert-type.d \ + cert.d \ + ciphers.d \ + compressed-ssh.d \ + compressed.d \ + config.d \ + connect-timeout.d \ + connect-to.d \ + continue-at.d \ + cookie-jar.d \ + cookie.d \ + create-dirs.d \ + create-file-mode.d \ + crlf.d \ + crlfile.d \ + curves.d \ + data-ascii.d \ + data-binary.d \ + data-raw.d \ + data-urlencode.d \ + data.d \ + delegation.d \ + digest.d \ + disable-eprt.d \ + disable-epsv.d \ + disable.d \ + disallow-username-in-url.d \ + dns-interface.d \ + dns-ipv4-addr.d \ + dns-ipv6-addr.d \ + dns-servers.d \ + doh-cert-status.d \ + doh-insecure.d \ + doh-url.d \ + dump-header.d \ + egd-file.d \ + engine.d \ + etag-compare.d \ + etag-save.d \ + expect100-timeout.d \ + fail-early.d \ + fail-with-body.d \ + fail.d \ + false-start.d \ + form-escape.d \ + form-string.d \ + form.d \ + ftp-account.d \ + ftp-alternative-to-user.d \ + ftp-create-dirs.d \ + ftp-method.d \ + ftp-pasv.d \ + ftp-port.d \ + ftp-pret.d \ + ftp-skip-pasv-ip.d \ + ftp-ssl-ccc-mode.d \ + ftp-ssl-ccc.d \ + ftp-ssl-control.d \ + get.d \ + globoff.d \ + happy-eyeballs-timeout-ms.d \ + haproxy-protocol.d \ + head.d \ + header.d \ + help.d \ + hostpubmd5.d \ + hostpubsha256.d \ + hsts.d \ + http0.9.d \ + http1.0.d \ + http1.1.d \ + http2-prior-knowledge.d \ + http2.d \ + http3.d \ + ignore-content-length.d \ + include.d \ + insecure.d \ + interface.d \ + ipv4.d \ + ipv6.d \ + json.d \ + junk-session-cookies.d \ + keepalive-time.d \ + key-type.d \ + key.d \ + krb.d \ + libcurl.d \ + limit-rate.d \ + list-only.d \ + local-port.d \ + location-trusted.d \ + location.d \ + login-options.d \ + mail-auth.d \ + mail-from.d \ + mail-rcpt-allowfails.d \ + mail-rcpt.d \ + manual.d \ + max-filesize.d \ + max-redirs.d \ + max-time.d \ + metalink.d \ + negotiate.d \ + netrc-file.d \ + netrc-optional.d \ + netrc.d \ + next.d \ + no-alpn.d \ + no-buffer.d \ + no-clobber.d \ + no-keepalive.d \ + no-npn.d \ + no-progress-meter.d \ + no-sessionid.d \ + noproxy.d \ + ntlm-wb.d \ + ntlm.d \ + oauth2-bearer.d \ + output-dir.d \ + output.d \ + parallel-immediate.d \ + parallel-max.d \ + parallel.d \ + pass.d \ + path-as-is.d \ + pinnedpubkey.d \ + post301.d \ + post302.d \ + post303.d \ + preproxy.d \ + progress-bar.d \ + proto-default.d \ + proto-redir.d \ + proto.d \ + proxy-anyauth.d \ + proxy-basic.d \ + proxy-cacert.d \ + proxy-capath.d \ + proxy-cert-type.d \ + proxy-cert.d \ + proxy-ciphers.d \ + proxy-crlfile.d \ + proxy-digest.d \ + proxy-header.d \ + proxy-insecure.d \ + proxy-key-type.d \ + proxy-key.d \ + proxy-negotiate.d \ + proxy-ntlm.d \ + proxy-pass.d \ + proxy-pinnedpubkey.d \ + proxy-service-name.d \ + proxy-ssl-allow-beast.d \ + proxy-ssl-auto-client-cert.d \ + proxy-tls13-ciphers.d \ + proxy-tlsauthtype.d \ + proxy-tlspassword.d \ + proxy-tlsuser.d \ + proxy-tlsv1.d \ + proxy-user.d \ + proxy.d \ + proxy1.0.d \ + proxytunnel.d \ + pubkey.d \ + quote.d \ + random-file.d \ + range.d \ + raw.d \ + referer.d \ + remote-header-name.d \ + remote-name-all.d \ + remote-name.d \ + remote-time.d \ + remove-on-error.d \ + request-target.d \ + request.d \ + resolve.d \ + retry-all-errors.d \ + retry-connrefused.d \ + retry-delay.d \ + retry-max-time.d \ + retry.d \ + sasl-authzid.d \ + sasl-ir.d \ + service-name.d \ + show-error.d \ + silent.d \ + socks4.d \ + socks4a.d \ + socks5-basic.d \ + socks5-gssapi-nec.d \ + socks5-gssapi-service.d \ + socks5-gssapi.d \ + socks5-hostname.d \ + socks5.d \ + speed-limit.d \ + speed-time.d \ + ssl-allow-beast.d \ + ssl-auto-client-cert.d \ + ssl-no-revoke.d \ + ssl-reqd.d \ + ssl-revoke-best-effort.d \ + ssl.d \ + sslv2.d \ + sslv3.d \ + stderr.d \ + styled-output.d \ + suppress-connect-headers.d \ + tcp-fastopen.d \ + tcp-nodelay.d \ + telnet-option.d \ + tftp-blksize.d \ + tftp-no-options.d \ + time-cond.d \ + tls-max.d \ + tls13-ciphers.d \ + tlsauthtype.d \ + tlspassword.d \ + tlsuser.d \ + tlsv1.0.d \ + tlsv1.1.d \ + tlsv1.2.d \ + tlsv1.3.d \ + tlsv1.d \ + tr-encoding.d \ + trace-ascii.d \ + trace-time.d \ + trace.d \ + unix-socket.d \ + upload-file.d \ + url.d \ + use-ascii.d \ + user-agent.d \ + user.d \ + verbose.d \ + version.d \ + write-out.d \ xattr.d OTHERPAGES = page-footer page-header diff --git a/extern/curl/docs/cmdline-opts/abstract-unix-socket.d b/extern/curl/docs/cmdline-opts/abstract-unix-socket.d index 1fda4e5df3..fcd2d94c98 100644 --- a/extern/curl/docs/cmdline-opts/abstract-unix-socket.d +++ b/extern/curl/docs/cmdline-opts/abstract-unix-socket.d @@ -3,6 +3,9 @@ Arg: Help: Connect via abstract Unix domain socket Added: 7.53.0 Protocols: HTTP +Category: connection +See-also: unix-socket +Example: --abstract-unix-socket socketpath $URL --- Connect through an abstract Unix domain socket, instead of using the network. Note: netstat shows the path of an abstract socket prefixed with '@', however diff --git a/extern/curl/docs/cmdline-opts/alt-svc.d b/extern/curl/docs/cmdline-opts/alt-svc.d index 15877a2fee..3ad2230494 100644 --- a/extern/curl/docs/cmdline-opts/alt-svc.d +++ b/extern/curl/docs/cmdline-opts/alt-svc.d @@ -3,9 +3,10 @@ Arg: Protocols: HTTPS Help: Enable alt-svc with this cache file Added: 7.64.1 +Category: http +See-also: resolve connect-to +Example: --alt-svc svc.txt $URL --- -WARNING: this option is experimental. Do not use in production. - This option enables the alt-svc parser in curl. If the file name points to an existing alt-svc cache file, that will be used. After a completed transfer, the cache will be saved to the file name again if it has been modified. diff --git a/extern/curl/docs/cmdline-opts/anyauth.d b/extern/curl/docs/cmdline-opts/anyauth.d index c32d1ed5ef..1092341724 100644 --- a/extern/curl/docs/cmdline-opts/anyauth.d +++ b/extern/curl/docs/cmdline-opts/anyauth.d @@ -2,6 +2,9 @@ Long: anyauth Help: Pick any authentication method Protocols: HTTP See-also: proxy-anyauth basic digest +Category: http proxy auth +Example: --anyauth --user me:pwd $URL +Added: 7.10.6 --- Tells curl to figure out authentication method by itself, and use the most secure one the remote site claims to support. This is done by first doing a diff --git a/extern/curl/docs/cmdline-opts/append.d b/extern/curl/docs/cmdline-opts/append.d index f001b1239d..7ea02d7086 100644 --- a/extern/curl/docs/cmdline-opts/append.d +++ b/extern/curl/docs/cmdline-opts/append.d @@ -2,7 +2,11 @@ Short: a Long: append Help: Append to target file when uploading Protocols: FTP SFTP +Category: ftp sftp +See-also: range continue-at +Example: --upload-file local --append ftp://example.com/ +Added: 4.8 --- When used in an upload, this makes curl append to the target file instead of -overwriting it. If the remote file doesn't exist, it will be created. Note +overwriting it. If the remote file does not exist, it will be created. Note that this flag is ignored by some SFTP servers (including OpenSSH). diff --git a/extern/curl/docs/cmdline-opts/aws-sigv4.d b/extern/curl/docs/cmdline-opts/aws-sigv4.d new file mode 100644 index 0000000000..c13b8da764 --- /dev/null +++ b/extern/curl/docs/cmdline-opts/aws-sigv4.d @@ -0,0 +1,19 @@ +Long: aws-sigv4 +Arg: +Help: Use AWS V4 signature authentication +Category: auth http +Added: 7.75.0 +See-also: basic user +Example: --aws-sigv4 "aws:amz:east-2:es" --user "key:secret" $URL +--- +Use AWS V4 signature authentication in the transfer. + +The provider argument is a string that is used by the algorithm when creating +outgoing authentication headers. + +The region argument is a string that points to a geographic area of +a resources collection (region-code) when the region name is omitted from +the endpoint. + +The service argument is a string that points to a function provided by a cloud +(service-code) when the service name is omitted from the endpoint. diff --git a/extern/curl/docs/cmdline-opts/basic.d b/extern/curl/docs/cmdline-opts/basic.d index 09d42af9d4..abab7d0683 100644 --- a/extern/curl/docs/cmdline-opts/basic.d +++ b/extern/curl/docs/cmdline-opts/basic.d @@ -2,6 +2,9 @@ Long: basic Help: Use HTTP Basic Authentication See-also: proxy-basic Protocols: HTTP +Category: auth +Example: -u name:password --basic $URL +Added: 7.10.6 --- Tells curl to use HTTP Basic authentication with the remote host. This is the default and this option is usually pointless, unless you use it to override a diff --git a/extern/curl/docs/cmdline-opts/cacert.d b/extern/curl/docs/cmdline-opts/cacert.d index 6a56787522..e066471c6c 100644 --- a/extern/curl/docs/cmdline-opts/cacert.d +++ b/extern/curl/docs/cmdline-opts/cacert.d @@ -2,6 +2,10 @@ Long: cacert Arg: Help: CA certificate to verify peer against Protocols: TLS +Category: tls +See-also: capath insecure +Example: --cacert CA-file.txt $URL +Added: 7.5 --- Tells curl to use the specified certificate file to verify the peer. The file may contain multiple CA certificates. The certificate(s) must be in PEM @@ -13,7 +17,7 @@ set, and uses the given path as a path to a CA cert bundle. This option overrides that variable. The windows version of curl will automatically look for a CA certs file named -\'curl-ca-bundle.crt\', either in the same directory as curl.exe, or in the +'curl-ca-bundle.crt', either in the same directory as curl.exe, or in the Current Working Directory, or in any folder along your PATH. If curl is built against the NSS SSL library, the NSS PEM PKCS#11 module @@ -25,9 +29,9 @@ should not be set. If the option is not set, then curl will use the certificates in the system and user Keychain to verify the peer, which is the preferred method of verifying the peer's certificate chain. -(Schannel only) This option is supported for Schannel in Windows 7 or later with -libcurl 7.60 or later. This option is supported for backward compatibility -with other SSL engines; instead it is recommended to use Windows' store of -root certificates (the default for Schannel). +(Schannel only) This option is supported for Schannel in Windows 7 or later +with libcurl 7.60 or later. This option is supported for backward +compatibility with other SSL engines; instead it is recommended to use +Windows' store of root certificates (the default for Schannel). If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/capath.d b/extern/curl/docs/cmdline-opts/capath.d index 0763f7a0d4..7f879a2a4b 100644 --- a/extern/curl/docs/cmdline-opts/capath.d +++ b/extern/curl/docs/cmdline-opts/capath.d @@ -2,6 +2,10 @@ Long: capath Arg: Help: CA directory to verify peer against Protocols: TLS +Category: tls +See-also: cacert insecure +Example: --capath /local/directory $URL +Added: 7.9.8 --- Tells curl to use the specified certificate directory to verify the peer. Multiple paths can be provided by separating them with ":" (e.g. diff --git a/extern/curl/docs/cmdline-opts/cert-status.d b/extern/curl/docs/cmdline-opts/cert-status.d index f1aaa21744..c3b9bdb361 100644 --- a/extern/curl/docs/cmdline-opts/cert-status.d +++ b/extern/curl/docs/cmdline-opts/cert-status.d @@ -1,7 +1,10 @@ Long: cert-status Protocols: TLS Added: 7.41.0 -Help: Verify the status of the server certificate +Help: Verify the status of the server cert via OCSP-staple +Category: tls +See-also: pinnedpubkey +Example: --cert-status $URL --- Tells curl to verify the status of the server certificate by using the Certificate Status Request (aka. OCSP stapling) TLS extension. diff --git a/extern/curl/docs/cmdline-opts/cert-type.d b/extern/curl/docs/cmdline-opts/cert-type.d index 55d8033b45..ead0e18f34 100644 --- a/extern/curl/docs/cmdline-opts/cert-type.d +++ b/extern/curl/docs/cmdline-opts/cert-type.d @@ -1,10 +1,17 @@ Long: cert-type Protocols: TLS Arg: -Help: Certificate file type +Help: Certificate type (DER/PEM/ENG/P12) See-also: cert key key-type +Category: tls +Example: --cert-type PEM --cert file $URL +Added: 7.9.3 --- Tells curl what type the provided client certificate is using. PEM, DER, ENG -and P12 are recognized types. If not specified, PEM is assumed. +and P12 are recognized types. + +The default type depends on the TLS backend and is usually PEM, however for +Secure Transport and Schannel it is P12. If --cert is a pkcs11: URI then ENG is +the default type. If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/cert.d b/extern/curl/docs/cmdline-opts/cert.d index de6b42060f..0e8776e2ef 100644 --- a/extern/curl/docs/cmdline-opts/cert.d +++ b/extern/curl/docs/cmdline-opts/cert.d @@ -4,11 +4,14 @@ Arg: Help: Client certificate file and password Protocols: TLS See-also: cert-type key key-type +Category: tls +Example: --cert certfile --key keyfile $URL +Added: 5.0 --- Tells curl to use the specified client certificate file when getting a file with HTTPS, FTPS or another SSL-based protocol. The certificate must be in PKCS#12 format if using Secure Transport, or PEM format if using any other -engine. If the optional password isn't specified, it will be queried for on +engine. If the optional password is not specified, it will be queried for on the terminal. Note that this option assumes a \&"certificate" file that is the private key and the client certificate concatenated! See --cert and --key to specify them independently. @@ -18,9 +21,9 @@ curl the nickname of the certificate to use within the NSS database defined by the environment variable SSL_DIR (or by default /etc/pki/nssdb). If the NSS PEM PKCS#11 module (libnsspem.so) is available then PEM files may be loaded. If you want to use a file from the current directory, please precede -it with "./" prefix, in order to avoid confusion with a nickname. If the +it with "./" prefix, in order to avoid confusion with a nickname. If the nickname contains ":", it needs to be preceded by "\\" so that it is not -recognized as password delimiter. If the nickname contains "\\", it needs to +recognized as password delimiter. If the nickname contains "\\", it needs to be escaped as "\\\\" so that it is not recognized as an escape character. If curl is built against OpenSSL library, and the engine pkcs11 is available, diff --git a/extern/curl/docs/cmdline-opts/ciphers.d b/extern/curl/docs/cmdline-opts/ciphers.d index 69e85525a5..24d3d5863c 100644 --- a/extern/curl/docs/cmdline-opts/ciphers.d +++ b/extern/curl/docs/cmdline-opts/ciphers.d @@ -2,10 +2,14 @@ Long: ciphers Arg: Help: SSL ciphers to use Protocols: TLS +Category: tls +See-also: tlsv1.3 +Example: --ciphers ECDHE-ECDSA-AES256-CCM8 $URL +Added: 7.9 --- Specifies which ciphers to use in the connection. The list of ciphers must specify valid ciphers. Read up on SSL cipher list details on this URL: - https://curl.haxx.se/docs/ssl-ciphers.html + https://curl.se/docs/ssl-ciphers.html If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/compressed-ssh.d b/extern/curl/docs/cmdline-opts/compressed-ssh.d index 583452ae47..0d198578b8 100644 --- a/extern/curl/docs/cmdline-opts/compressed-ssh.d +++ b/extern/curl/docs/cmdline-opts/compressed-ssh.d @@ -2,6 +2,9 @@ Long: compressed-ssh Help: Enable SSH compression Protocols: SCP SFTP Added: 7.56.0 +Category: scp ssh +See-also: compressed +Example: --compressed-ssh sftp://example.com/ --- Enables built-in SSH compression. This is a request, not an order; the server may or may not do it. diff --git a/extern/curl/docs/cmdline-opts/compressed.d b/extern/curl/docs/cmdline-opts/compressed.d index dc130c1f02..8e8db97ccb 100644 --- a/extern/curl/docs/cmdline-opts/compressed.d +++ b/extern/curl/docs/cmdline-opts/compressed.d @@ -1,7 +1,14 @@ Long: compressed Help: Request compressed response Protocols: HTTP +Category: http +Example: --compressed $URL +See-also: compressed-ssh +Added: 7.10 --- Request a compressed response using one of the algorithms curl supports, and -save the uncompressed document. If this option is used and the server sends -an unsupported encoding, curl will report an error. +automatically decompress the content. Headers are not modified. + +If this option is used and the server sends an unsupported encoding, curl will +report an error. This is a request, not an order; the server may or may not +deliver data compressed. diff --git a/extern/curl/docs/cmdline-opts/config.d b/extern/curl/docs/cmdline-opts/config.d index df3d39220a..96bb81ac3e 100644 --- a/extern/curl/docs/cmdline-opts/config.d +++ b/extern/curl/docs/cmdline-opts/config.d @@ -2,8 +2,11 @@ Long: config Arg: Help: Read config from a file Short: K +Category: curl +Example: --config file.txt $URL +Added: 4.10 +See-also: disable --- - Specify a text file to read curl arguments from. The command line arguments found in the text file will be used as if they were provided on the command line. @@ -18,9 +21,12 @@ between the option and its parameter. If the parameter contains whitespace (or starts with : or =), the parameter must be enclosed within quotes. Within double quotes, the following escape sequences are available: \\\\, \\", \\t, \\n, \\r and \\v. A backslash -preceding any other letter is ignored. If the first column of a config line is -a '#' character, the rest of the line will be treated as a comment. Only write -one option per physical line in the config file. +preceding any other letter is ignored. + +If the first column of a config line is a '#' character, the rest of the line +will be treated as a comment. + +Only write one option per physical line in the config file. Specify the filename to --config as '-' to make curl read the file from stdin. @@ -28,34 +34,42 @@ Note that to be able to specify a URL in the config file, you need to specify it using the --url option, and not by simply writing the URL on its own line. So, it could look similar to this: -url = "https://curl.haxx.se/docs/" +url = "https://curl.se/docs/" + + # --- Example file --- + # this is a comment + url = "example.com" + output = "curlhere.html" + user-agent = "superagent/1.0" + + # and fetch another URL too + url = "example.com/docs/manpage.html" + -O + referer = "http://nowhereatall.example.com/" + # --- End of example file --- When curl is invoked, it (unless --disable is used) checks for a default -config file and uses it if found. The default config file is checked for in -the following places in this order: - -1) curl tries to find the "home dir": It first checks for the CURL_HOME and -then the HOME environment variables. Failing that, it uses getpwuid() on -Unix-like systems (which returns the home dir given the current user in your -system). On Windows, it then checks for the APPDATA variable, or as a last -resort the '%USERPROFILE%\\Application Data'. - -2) On windows, if there is no .curlrc file in the home dir, it checks for one -in the same dir the curl executable is placed. On Unix-like systems, it will -simply try to load .curlrc from the determined home dir. - -.nf -# --- Example file --- -# this is a comment -url = "example.com" -output = "curlhere.html" -user-agent = "superagent/1.0" - -# and fetch another URL too -url = "example.com/docs/manpage.html" --O -referer = "http://nowhereatall.example.com/" -# --- End of example file --- -.fi +config file and uses it if found, even when --config is used. The default +config file is checked for in the following places in this order: + +1) "$CURL_HOME/.curlrc" + +2) "$XDG_CONFIG_HOME/.curlrc" (Added in 7.73.0) + +3) "$HOME/.curlrc" + +4) Windows: "%USERPROFILE%\\.curlrc" + +5) Windows: "%APPDATA%\\.curlrc" + +6) Windows: "%USERPROFILE%\\Application Data\\.curlrc" + +7) Non-Windows: use getpwuid to find the home directory + +8) On Windows, if it finds no .curlrc file in the sequence described above, it +checks for one in the same dir the curl executable is placed. + +On Windows two filenames are checked per location: .curlrc and _curlrc, +preferring the former. Older versions on Windows checked for _curlrc only. This option can be used multiple times to load multiple config files. diff --git a/extern/curl/docs/cmdline-opts/connect-timeout.d b/extern/curl/docs/cmdline-opts/connect-timeout.d index 3a32d86853..89152baa32 100644 --- a/extern/curl/docs/cmdline-opts/connect-timeout.d +++ b/extern/curl/docs/cmdline-opts/connect-timeout.d @@ -1,7 +1,11 @@ Long: connect-timeout -Arg: +Arg: Help: Maximum time allowed for connection See-also: max-time +Category: connection +Example: --connect-timeout 20 $URL +Example: --connect-timeout 3.14 $URL +Added: 7.7 --- Maximum time in seconds that you allow curl's connection to take. This only limits the connection phase, so if curl connects within the given period it diff --git a/extern/curl/docs/cmdline-opts/connect-to.d b/extern/curl/docs/cmdline-opts/connect-to.d index 458bfe855f..ebea9b9dae 100644 --- a/extern/curl/docs/cmdline-opts/connect-to.d +++ b/extern/curl/docs/cmdline-opts/connect-to.d @@ -3,6 +3,8 @@ Arg: Help: Connect to host Added: 7.49.0 See-also: resolve header +Category: connection +Example: --connect-to example.com:443:example.net:8443 $URL --- For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead. diff --git a/extern/curl/docs/cmdline-opts/continue-at.d b/extern/curl/docs/cmdline-opts/continue-at.d index 733f4941ea..b66116c8e9 100644 --- a/extern/curl/docs/cmdline-opts/continue-at.d +++ b/extern/curl/docs/cmdline-opts/continue-at.d @@ -3,10 +3,14 @@ Long: continue-at Arg: Help: Resumed transfer offset See-also: range +Category: connection +Example: -C - $URL +Example: -C 400 $URL +Added: 4.8 --- Continue/Resume a previous file transfer at the given offset. The given offset is the exact number of bytes that will be skipped, counting from the beginning -of the source file before it is transferred to the destination. If used with +of the source file before it is transferred to the destination. If used with uploads, the FTP server command SIZE will not be used by curl. Use "-C -" to tell curl to automatically find out where/how to resume the diff --git a/extern/curl/docs/cmdline-opts/cookie-jar.d b/extern/curl/docs/cmdline-opts/cookie-jar.d index da79777eb6..0a02c05b59 100644 --- a/extern/curl/docs/cmdline-opts/cookie-jar.d +++ b/extern/curl/docs/cmdline-opts/cookie-jar.d @@ -3,6 +3,11 @@ Long: cookie-jar Arg: Protocols: HTTP Help: Write cookies to after operation +Category: http +Example: -c store-here.txt $URL +Example: -c store-here.txt -b read-these $URL +Added: 7.9 +See-also: cookie --- Specify to which file you want curl to write all cookies after a completed operation. Curl writes all cookies from its in-memory cookie storage to the @@ -15,10 +20,10 @@ This command line option will activate the cookie engine that makes curl record and use cookies. Another way to activate it is to use the --cookie option. -If the cookie jar can't be created or written to, the whole curl operation -won't fail or even report an error clearly. Using --verbose will get a warning -displayed, but that is the only visible feedback you get about this possibly -lethal situation. +If the cookie jar cannot be created or written to, the whole curl operation +will not fail or even report an error clearly. Using --verbose will get a +warning displayed, but that is the only visible feedback you get about this +possibly lethal situation. If this option is used several times, the last specified file name will be used. diff --git a/extern/curl/docs/cmdline-opts/cookie.d b/extern/curl/docs/cmdline-opts/cookie.d index 1e9906977e..62208e73af 100644 --- a/extern/curl/docs/cmdline-opts/cookie.d +++ b/extern/curl/docs/cmdline-opts/cookie.d @@ -3,17 +3,25 @@ Long: cookie Arg: Protocols: HTTP Help: Send cookies from string/file +Category: http +Example: -b cookiefile $URL +Example: -b cookiefile -c cookiefile $URL +See-also: cookie-jar junk-session-cookies +Added: 4.9 --- -Pass the data to the HTTP server in the Cookie header. It is supposedly -the data previously received from the server in a "Set-Cookie:" line. The -data should be in the format "NAME1=VALUE1; NAME2=VALUE2". +Pass the data to the HTTP server in the Cookie header. It is supposedly the +data previously received from the server in a "Set-Cookie:" line. The data +should be in the format "NAME1=VALUE1; NAME2=VALUE2". This makes curl use the +cookie header with this content explicitly in all outgoing request(s). If +multiple requests are done due to authentication, followed redirects or +similar, they will all get this cookie passed on. If no '=' symbol is used in the argument, it is instead treated as a filename to read previously stored cookie from. This option also activates the cookie engine which will make curl record incoming cookies, which may be handy if -you're using this in combination with the --location option or do multiple URL +you are using this in combination with the --location option or do multiple URL transfers on the same invoke. If the file name is exactly a minus ("-"), curl -will instead the contents from stdin. +will instead read the contents from stdin. The file format of the file to read cookies from should be plain HTTP headers (Set-Cookie style) or the Netscape/Mozilla cookie file format. @@ -21,17 +29,13 @@ The file format of the file to read cookies from should be plain HTTP headers The file specified with --cookie is only used as input. No cookies will be written to the file. To store cookies, use the --cookie-jar option. -Exercise caution if you are using this option and multiple transfers may -occur. If you use the NAME1=VALUE1; format, or in a file use the Set-Cookie -format and don't specify a domain, then the cookie is sent for any domain -(even after redirects are followed) and cannot be modified by a server-set -cookie. If the cookie engine is enabled and a server sets a cookie of the same -name then both will be sent on a future transfer to that server, likely not -what you intended. To address these issues set a domain in Set-Cookie (doing -that will include sub domains) or use the Netscape format. +If you use the Set-Cookie file format and do not specify a domain then the +cookie is not sent since the domain will never match. To address this, set a +domain in Set-Cookie line (doing that will include sub-domains) or preferably: +use the Netscape format. -If this option is used several times, the last one will be used. +This option can be used multiple times. -Users very often want to both read cookies from a file and write updated -cookies back to a file, so using both --cookie and --cookie-jar in the same -command line is common. +Users often want to both read cookies from a file and write updated cookies +back to a file, so using both --cookie and --cookie-jar in the same command +line is common. diff --git a/extern/curl/docs/cmdline-opts/create-dirs.d b/extern/curl/docs/cmdline-opts/create-dirs.d index b09d96ca7f..5d20659034 100644 --- a/extern/curl/docs/cmdline-opts/create-dirs.d +++ b/extern/curl/docs/cmdline-opts/create-dirs.d @@ -1,10 +1,15 @@ Long: create-dirs Help: Create necessary local directory hierarchy +Category: curl +Example: --create-dirs --output local/dir/file $URL +Added: 7.10.3 +See-also: ftp-create-dirs output-dir --- When used in conjunction with the --output option, curl will create the -necessary local directory hierarchy as needed. This option creates the dirs -mentioned with the --output option, nothing else. If the --output file name -uses no dir or if the dirs it mentions already exist, no dir will be created. +necessary local directory hierarchy as needed. This option creates the +directories mentioned with the --output option, nothing else. If the --output +file name uses no directory, or if the directories it mentions already exist, +no directories will be created. Created dirs are made with mode 0750 on unix style file systems. diff --git a/extern/curl/docs/cmdline-opts/create-file-mode.d b/extern/curl/docs/cmdline-opts/create-file-mode.d new file mode 100644 index 0000000000..429b5ee33c --- /dev/null +++ b/extern/curl/docs/cmdline-opts/create-file-mode.d @@ -0,0 +1,16 @@ +Long: create-file-mode +Arg: +Help: File mode for created files +Protocols: SFTP SCP FILE +Category: sftp scp file upload +See-also: ftp-create-dirs +Added: 7.75.0 +Example: --create-file-mode 0777 -T localfile sftp://example.com/new +--- +When curl is used to create files remotely using one of the supported +protocols, this option allows the user to set which 'mode' to set on the file +at creation time, instead of the default 0644. + +This option takes an octal number as argument. + +If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/crlf.d b/extern/curl/docs/cmdline-opts/crlf.d index f6694b654d..3772fcf2c9 100644 --- a/extern/curl/docs/cmdline-opts/crlf.d +++ b/extern/curl/docs/cmdline-opts/crlf.d @@ -1,6 +1,10 @@ Long: crlf Help: Convert LF to CRLF in upload Protocols: FTP SMTP +Category: ftp smtp +Example: --crlf -T file ftp://example.com/ +Added: 5.7 +See-also: use-ascii --- Convert LF to CRLF in upload. Useful for MVS (OS/390). diff --git a/extern/curl/docs/cmdline-opts/crlfile.d b/extern/curl/docs/cmdline-opts/crlfile.d index 0fcc63c85d..1fdc125751 100644 --- a/extern/curl/docs/cmdline-opts/crlfile.d +++ b/extern/curl/docs/cmdline-opts/crlfile.d @@ -1,8 +1,11 @@ Long: crlfile Arg: Protocols: TLS -Help: Get a CRL list in PEM format from the given file +Help: Use this CRL list Added: 7.19.7 +Category: tls +Example: --crlfile rejects.txt $URL +See-also: cacert capath --- Provide a file using PEM format with a Certificate Revocation List that may specify peer certificates that are to be considered revoked. diff --git a/extern/curl/docs/cmdline-opts/curves.d b/extern/curl/docs/cmdline-opts/curves.d new file mode 100644 index 0000000000..b4cb43f045 --- /dev/null +++ b/extern/curl/docs/cmdline-opts/curves.d @@ -0,0 +1,20 @@ +Long: curves +Arg: +Help: (EC) TLS key exchange algorithm(s) to request +Protocols: TLS +Added: 7.73.0 +Category: tls +Example: --curves X25519 $URL +See-also: ciphers +--- +Tells curl to request specific curves to use during SSL session establishment +according to RFC 8422, 5.1. Multiple algorithms can be provided by separating +them with ":" (e.g. "X25519:P-521"). The parameter is available identically +in the "openssl s_client/s_server" utilities. + +--curves allows a OpenSSL powered curl to make SSL-connections with exactly +the (EC) curve requested by the client, avoiding nontransparent client/server +negotiations. + +If this option is set, the default curves list built into openssl will be +ignored. diff --git a/extern/curl/docs/cmdline-opts/data-ascii.d b/extern/curl/docs/cmdline-opts/data-ascii.d index bda4abc3d1..52366dc43d 100644 --- a/extern/curl/docs/cmdline-opts/data-ascii.d +++ b/extern/curl/docs/cmdline-opts/data-ascii.d @@ -2,5 +2,9 @@ Long: data-ascii Arg: Help: HTTP POST ASCII data Protocols: HTTP +Category: http post upload +Example: --data-ascii @file $URL +Added: 7.2 +See-also: data-binary data-raw data-urlencode --- This is just an alias for --data. diff --git a/extern/curl/docs/cmdline-opts/data-binary.d b/extern/curl/docs/cmdline-opts/data-binary.d index 3f6ff2dbd0..32152ee606 100644 --- a/extern/curl/docs/cmdline-opts/data-binary.d +++ b/extern/curl/docs/cmdline-opts/data-binary.d @@ -2,10 +2,14 @@ Long: data-binary Arg: Help: HTTP POST binary data Protocols: HTTP +Category: http post upload +Example: --data-binary @filename $URL +Added: 7.2 +See-also: data-ascii --- This posts data exactly as specified with no extra processing whatsoever. -If you start the data with the letter @, the rest should be a filename. Data +If you start the data with the letter @, the rest should be a filename. Data is posted in a similar manner as --data does, except that newlines and carriage returns are preserved and conversions are never done. diff --git a/extern/curl/docs/cmdline-opts/data-raw.d b/extern/curl/docs/cmdline-opts/data-raw.d index 7669b4abfa..b8cd0f7211 100644 --- a/extern/curl/docs/cmdline-opts/data-raw.d +++ b/extern/curl/docs/cmdline-opts/data-raw.d @@ -4,6 +4,9 @@ Protocols: HTTP Help: HTTP POST data, '@' allowed Added: 7.43.0 See-also: data +Category: http post upload +Example: --data-raw "hello" $URL +Example: --data-raw "@at@at@" $URL --- This posts data similarly to --data but without the special interpretation of the @ character. diff --git a/extern/curl/docs/cmdline-opts/data-urlencode.d b/extern/curl/docs/cmdline-opts/data-urlencode.d index 9873f3356e..a0fc75b665 100644 --- a/extern/curl/docs/cmdline-opts/data-urlencode.d +++ b/extern/curl/docs/cmdline-opts/data-urlencode.d @@ -1,20 +1,25 @@ Long: data-urlencode Arg: -Help: HTTP POST data url encoded +Help: HTTP POST data URL encoded Protocols: HTTP See-also: data data-raw Added: 7.18.0 +Category: http post upload +Example: --data-urlencode name=val $URL +Example: --data-urlencode =encodethis $URL +Example: --data-urlencode name@file $URL +Example: --data-urlencode @fileonly $URL --- This posts data, similar to the other --data options with the exception that this performs URL-encoding. -To be CGI-compliant, the part should begin with a \fIname\fP followed +To be CGI-compliant, the part should begin with a *name* followed by a separator and a content specification. The part can be passed to curl using one of the following syntaxes: .RS .IP "content" This will make curl URL-encode the content and pass that on. Just be careful -so that the content doesn't contain any = or @ symbols, as that will then make +so that the content does not contain any = or @ symbols, as that will then make the syntax match one of the other cases below! .IP "=content" This will make curl URL-encode the content and pass that on. The preceding = @@ -28,6 +33,6 @@ URL-encode that data and pass it on in the POST. .IP "name@filename" This will make curl load data from the given file (including any newlines), URL-encode that data and pass it on in the POST. The name part gets an equal -sign appended, resulting in \fIname=urlencoded-file-content\fP. Note that the +sign appended, resulting in *name=urlencoded-file-content*. Note that the name is expected to be URL-encoded already. .RE diff --git a/extern/curl/docs/cmdline-opts/data.d b/extern/curl/docs/cmdline-opts/data.d index 8b5200d34a..682314c022 100644 --- a/extern/curl/docs/cmdline-opts/data.d +++ b/extern/curl/docs/cmdline-opts/data.d @@ -2,28 +2,33 @@ Long: data Short: d Arg: Help: HTTP POST data -Protocols: HTTP +Protocols: HTTP MQTT See-also: data-binary data-urlencode data-raw Mutexed: form head upload-file +Category: important http post upload +Example: -d "name=curl" $URL +Example: -d "name=curl" -d "tool=cmdline" $URL +Example: -d @filename $URL +Added: 4.0 --- Sends the specified data in a POST request to the HTTP server, in the same way that a browser does when a user has filled in an HTML form and presses the submit button. This will cause curl to pass the data to the server using the -content-type application/x-www-form-urlencoded. Compare to --form. +content-type application/x-www-form-urlencoded. Compare to --form. --data-raw is almost the same but does not have a special interpretation of the @ character. To post data purely binary, you should instead use the ---data-binary option. To URL-encode the value of a form field you may use +--data-binary option. To URL-encode the value of a form field you may use --data-urlencode. If any of these options is used more than once on the same command line, the -data pieces specified will be merged together with a separating -&-symbol. Thus, using '-d name=daniel -d skill=lousy' would generate a post -chunk that looks like \&'name=daniel&skill=lousy'. +data pieces specified will be merged with a separating &-symbol. Thus, using +\&'-d name=daniel -d skill=lousy' would generate a post chunk that looks like +\&'name=daniel&skill=lousy'. If you start the data with the letter @, the rest should be a file name to read the data from, or - if you want curl to read the data from stdin. Posting data from a file named \&'foobar' would thus be done with --data @foobar. When --data is told to read from a file like that, carriage returns and newlines -will be stripped out. If you don't want the @ character to have a special +will be stripped out. If you do not want the @ character to have a special interpretation use --data-raw instead. diff --git a/extern/curl/docs/cmdline-opts/delegation.d b/extern/curl/docs/cmdline-opts/delegation.d index 138d82333e..858ff0406f 100644 --- a/extern/curl/docs/cmdline-opts/delegation.d +++ b/extern/curl/docs/cmdline-opts/delegation.d @@ -2,15 +2,21 @@ Long: delegation Arg: Help: GSS-API delegation permission Protocols: GSS/kerberos +Category: auth +Example: --delegation "none" $URL +Added: 7.22.0 +See-also: insecure ssl --- Set LEVEL to tell the server what it is allowed to delegate when it comes to user credentials. .RS .IP "none" -Don't allow any delegation. +Do not allow any delegation. .IP "policy" Delegates if and only if the OK-AS-DELEGATE flag is set in the Kerberos service ticket, which is a matter of realm policy. .IP "always" Unconditionally allow the server to delegate. .RE + +If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/digest.d b/extern/curl/docs/cmdline-opts/digest.d index 5cdd9258a0..4feb8505db 100644 --- a/extern/curl/docs/cmdline-opts/digest.d +++ b/extern/curl/docs/cmdline-opts/digest.d @@ -3,6 +3,9 @@ Help: Use HTTP Digest Authentication Protocols: HTTP Mutexed: basic ntlm negotiate See-also: user proxy-digest anyauth +Category: proxy auth http +Example: -u name:password --digest $URL +Added: 7.10.6 --- Enables HTTP Digest authentication. This is an authentication scheme that prevents the password from being sent over the wire in clear text. Use this in diff --git a/extern/curl/docs/cmdline-opts/disable-eprt.d b/extern/curl/docs/cmdline-opts/disable-eprt.d index a1e53c0bd1..6b82f13760 100644 --- a/extern/curl/docs/cmdline-opts/disable-eprt.d +++ b/extern/curl/docs/cmdline-opts/disable-eprt.d @@ -1,6 +1,10 @@ Long: disable-eprt Help: Inhibit using EPRT or LPRT Protocols: FTP +Category: ftp +Example: --disable-eprt ftp://example.com/ +Added: 7.10.5 +See-also: disable-epsv ftp-port --- Tell curl to disable the use of the EPRT and LPRT commands when doing active FTP transfers. Curl will normally always first attempt to use EPRT, then LPRT diff --git a/extern/curl/docs/cmdline-opts/disable-epsv.d b/extern/curl/docs/cmdline-opts/disable-epsv.d index 6d2cb70898..4684726261 100644 --- a/extern/curl/docs/cmdline-opts/disable-epsv.d +++ b/extern/curl/docs/cmdline-opts/disable-epsv.d @@ -1,10 +1,14 @@ Long: disable-epsv Help: Inhibit using EPSV Protocols: FTP +Category: ftp +Example: --disable-epsv ftp://example.com/ +Added: 7.9.2 +See-also: disable-eprt ftp-port --- -(FTP) Tell curl to disable the use of the EPSV command when doing passive FTP -transfers. Curl will normally always first attempt to use EPSV before PASV, -but with this option, it will not try using EPSV. +Tell curl to disable the use of the EPSV command when doing passive FTP +transfers. Curl will normally always first attempt to use EPSV before +PASV, but with this option, it will not try using EPSV. --epsv can be used to explicitly enable EPSV again and --no-epsv is an alias for --disable-epsv. diff --git a/extern/curl/docs/cmdline-opts/disable.d b/extern/curl/docs/cmdline-opts/disable.d index 20b27b4c52..e417571f17 100644 --- a/extern/curl/docs/cmdline-opts/disable.d +++ b/extern/curl/docs/cmdline-opts/disable.d @@ -1,7 +1,11 @@ Long: disable Short: q Help: Disable .curlrc +Category: curl +Example: -q $URL +Added: 5.0 +See-also: config --- -If used as the first parameter on the command line, the \fIcurlrc\fP config +If used as the first parameter on the command line, the *curlrc* config file will not be read and used. See the --config for details on the default config file search path. diff --git a/extern/curl/docs/cmdline-opts/disallow-username-in-url.d b/extern/curl/docs/cmdline-opts/disallow-username-in-url.d index a7f46ea15c..c60e2253e4 100644 --- a/extern/curl/docs/cmdline-opts/disallow-username-in-url.d +++ b/extern/curl/docs/cmdline-opts/disallow-username-in-url.d @@ -1,7 +1,10 @@ Long: disallow-username-in-url -Help: Disallow username in url +Help: Disallow username in URL Protocols: HTTP Added: 7.61.0 See-also: proto +Category: curl http +Example: --disallow-username-in-url $URL --- -This tells curl to exit if passed a url containing a username. +This tells curl to exit if passed a URL containing a username. This is probably +most useful when the URL is being provided at runtime or similar. diff --git a/extern/curl/docs/cmdline-opts/dns-interface.d b/extern/curl/docs/cmdline-opts/dns-interface.d index 45e5af263e..fec7927eb6 100644 --- a/extern/curl/docs/cmdline-opts/dns-interface.d +++ b/extern/curl/docs/cmdline-opts/dns-interface.d @@ -5,6 +5,8 @@ Protocols: DNS See-also: dns-ipv4-addr dns-ipv6-addr Added: 7.33.0 Requires: c-ares +Category: dns +Example: --dns-interface eth0 $URL --- Tell curl to send outgoing DNS requests through . This option is a counterpart to --interface (which does not affect DNS). The supplied string diff --git a/extern/curl/docs/cmdline-opts/dns-ipv4-addr.d b/extern/curl/docs/cmdline-opts/dns-ipv4-addr.d index 597b858845..e09153ab49 100644 --- a/extern/curl/docs/cmdline-opts/dns-ipv4-addr.d +++ b/extern/curl/docs/cmdline-opts/dns-ipv4-addr.d @@ -5,7 +5,11 @@ Protocols: DNS See-also: dns-interface dns-ipv6-addr Added: 7.33.0 Requires: c-ares +Category: dns +Example: --dns-ipv4-addr 10.1.2.3 $URL --- Tell curl to bind to when making IPv4 DNS requests, so that the DNS requests originate from this address. The argument should be a single IPv4 address. + +If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/dns-ipv6-addr.d b/extern/curl/docs/cmdline-opts/dns-ipv6-addr.d index 581f019537..954cb98b32 100644 --- a/extern/curl/docs/cmdline-opts/dns-ipv6-addr.d +++ b/extern/curl/docs/cmdline-opts/dns-ipv6-addr.d @@ -5,7 +5,11 @@ Protocols: DNS See-also: dns-interface dns-ipv4-addr Added: 7.33.0 Requires: c-ares +Category: dns +Example: --dns-ipv6-addr 2a04:4e42::561 $URL --- Tell curl to bind to when making IPv6 DNS requests, so that the DNS requests originate from this address. The argument should be a single IPv6 address. + +If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/dns-servers.d b/extern/curl/docs/cmdline-opts/dns-servers.d index a98fd07d89..8a2341528b 100644 --- a/extern/curl/docs/cmdline-opts/dns-servers.d +++ b/extern/curl/docs/cmdline-opts/dns-servers.d @@ -3,8 +3,13 @@ Arg: Help: DNS server addrs to use Requires: c-ares Added: 7.33.0 +Category: dns +Example: --dns-servers 192.168.0.1,192.168.0.2 $URL +See-also: dns-interface dns-ipv4-addr --- Set the list of DNS servers to be used instead of the system default. The list of IP addresses should be separated with commas. Port numbers -may also optionally be given as \fI:\fP after each IP +may also optionally be given as *:* after each IP address. + +If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/doh-cert-status.d b/extern/curl/docs/cmdline-opts/doh-cert-status.d new file mode 100644 index 0000000000..0846ccb770 --- /dev/null +++ b/extern/curl/docs/cmdline-opts/doh-cert-status.d @@ -0,0 +1,8 @@ +Long: doh-cert-status +Help: Verify the status of the DoH server cert via OCSP-staple +Added: 7.76.0 +Category: dns tls +Example: --doh-cert-status --doh-url https://doh.example $URL +See-also: doh-insecure +--- +Same as --cert-status but used for DoH (DNS-over-HTTPS). diff --git a/extern/curl/docs/cmdline-opts/doh-insecure.d b/extern/curl/docs/cmdline-opts/doh-insecure.d new file mode 100644 index 0000000000..9430bd4d09 --- /dev/null +++ b/extern/curl/docs/cmdline-opts/doh-insecure.d @@ -0,0 +1,8 @@ +Long: doh-insecure +Help: Allow insecure DoH server connections +Added: 7.76.0 +Category: dns tls +Example: --doh-insecure --doh-url https://doh.example $URL +See-also: doh-url +--- +Same as --insecure but used for DoH (DNS-over-HTTPS). diff --git a/extern/curl/docs/cmdline-opts/doh-url.d b/extern/curl/docs/cmdline-opts/doh-url.d index c871c4d221..c64cca289a 100644 --- a/extern/curl/docs/cmdline-opts/doh-url.d +++ b/extern/curl/docs/cmdline-opts/doh-url.d @@ -1,10 +1,17 @@ Long: doh-url Arg: -Help: Resolve host names over DOH -Protocols: all +Help: Resolve host names over DoH Added: 7.62.0 +Category: dns +Example: --doh-url https://doh.example $URL +See-also: doh-insecure --- -Specifies which DNS-over-HTTPS (DOH) server to use to resolve hostnames, +Specifies which DNS-over-HTTPS (DoH) server to use to resolve hostnames, instead of using the default name resolver mechanism. The URL must be HTTPS. +Some SSL options that you set for your transfer will apply to DoH since the +name lookups take place over SSL. However, the certificate verification +settings are not inherited and can be controlled separately via +--doh-insecure and --doh-cert-status. + If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/dump-header.d b/extern/curl/docs/cmdline-opts/dump-header.d index 33c6674e80..8c617b92c6 100644 --- a/extern/curl/docs/cmdline-opts/dump-header.d +++ b/extern/curl/docs/cmdline-opts/dump-header.d @@ -4,15 +4,12 @@ Arg: Help: Write the received headers to Protocols: HTTP FTP See-also: output +Category: http ftp +Example: --dump-header store.txt $URL +Added: 5.7 --- -Write the received protocol headers to the specified file. - -This option is handy to use when you want to store the headers that an HTTP -site sends to you. Cookies from the headers could then be read in a second -curl invocation by using the --cookie option! The --cookie-jar option is a -better way to store cookies. - -If no headers are received, the use of this option will create an empty file. +Write the received protocol headers to the specified file. If no headers are +received, the use of this option will create an empty file. When used in FTP, the FTP server response lines are considered being "headers" and thus are saved there. diff --git a/extern/curl/docs/cmdline-opts/egd-file.d b/extern/curl/docs/cmdline-opts/egd-file.d index c22790f6ae..cd3450a214 100644 --- a/extern/curl/docs/cmdline-opts/egd-file.d +++ b/extern/curl/docs/cmdline-opts/egd-file.d @@ -3,6 +3,9 @@ Arg: Help: EGD socket path for random data Protocols: TLS See-also: random-file +Category: tls +Example: --egd-file /random/here $URL +Added: 7.7 --- Specify the path name to the Entropy Gathering Daemon socket. The socket is used to seed the random engine for SSL connections. diff --git a/extern/curl/docs/cmdline-opts/engine.d b/extern/curl/docs/cmdline-opts/engine.d index cde1a47735..61c41ce750 100644 --- a/extern/curl/docs/cmdline-opts/engine.d +++ b/extern/curl/docs/cmdline-opts/engine.d @@ -2,7 +2,11 @@ Long: engine Arg: Help: Crypto engine to use Protocols: TLS +Category: tls +Example: --engine flavor $URL +Added: 7.9.3 +See-also: ciphers curves --- Select the OpenSSL crypto engine to use for cipher operations. Use --engine -list to print a list of build-time supported engines. Note that not all (or -none) of the engines may be available at run-time. +list to print a list of build-time supported engines. Note that not all (and +possibly none) of the engines may be available at runtime. diff --git a/extern/curl/docs/cmdline-opts/etag-compare.d b/extern/curl/docs/cmdline-opts/etag-compare.d index 1a698a8ffe..494633f5cd 100644 --- a/extern/curl/docs/cmdline-opts/etag-compare.d +++ b/extern/curl/docs/cmdline-opts/etag-compare.d @@ -3,16 +3,18 @@ Arg: Help: Pass an ETag from a file as a custom header Protocols: HTTP Added: 7.68.0 +Category: http +Example: --etag-compare etag.txt $URL +See-also: etag-save time-cond --- -This option makes a conditional HTTP request for the specific -ETag read from the given file by sending a custom If-None-Match -header using the extracted ETag. +This option makes a conditional HTTP request for the specific ETag read +from the given file by sending a custom If-None-Match header using the +stored ETag. -For correct results, make sure that specified file contains only a single -line with a desired ETag. An empty file is parsed as an empty ETag. +For correct results, make sure that the specified file contains only a +single line with the desired ETag. An empty file is parsed as an empty +ETag. Use the option --etag-save to first save the ETag from a response, and -then use this option to compare using the saved ETag in a subsequent request. - -\fCOMPARISON\fP: There are 2 types of comparison or ETags, Weak and Strong. -This option expects, and uses a strong comparison. +then use this option to compare against the saved ETag in a subsequent +request. diff --git a/extern/curl/docs/cmdline-opts/etag-save.d b/extern/curl/docs/cmdline-opts/etag-save.d index 214723ff51..5cce0ee1ce 100644 --- a/extern/curl/docs/cmdline-opts/etag-save.d +++ b/extern/curl/docs/cmdline-opts/etag-save.d @@ -3,14 +3,11 @@ Arg: Help: Parse ETag from a request and save it to a file Protocols: HTTP Added: 7.68.0 +Category: http +Example: --etag-save storetag.txt $URL +See-also: etag-compare --- -This option saves an HTTP ETag to the specified file. Etag is -usually part of headers returned by a request. When server sends an -ETag, it must be enveloped by a double quote. This option extracts the -ETag without the double quotes and saves it into the . +This option saves an HTTP ETag to the specified file. An ETag is a +caching related header, usually returned in a response. -A server can send a week ETag which is prefixed by "W/". This identifier -is not considered, and only relevant ETag between quotation marks is parsed. - -It an ETag wasn't send by the server or it cannot be parsed, and empty -file is created. +If no ETag is sent by the server, an empty file is created. diff --git a/extern/curl/docs/cmdline-opts/expect100-timeout.d b/extern/curl/docs/cmdline-opts/expect100-timeout.d index c88f0b84fd..8855edd0b7 100644 --- a/extern/curl/docs/cmdline-opts/expect100-timeout.d +++ b/extern/curl/docs/cmdline-opts/expect100-timeout.d @@ -4,6 +4,8 @@ Help: How long to wait for 100-continue Protocols: HTTP Added: 7.47.0 See-also: connect-timeout +Category: http +Example: --expect100-timeout 2.5 -T file $URL --- Maximum time in seconds that you allow curl to wait for a 100-continue response when curl emits an Expects: 100-continue header in its request. By diff --git a/extern/curl/docs/cmdline-opts/fail-early.d b/extern/curl/docs/cmdline-opts/fail-early.d index 375d4c9195..fc3e45aef7 100644 --- a/extern/curl/docs/cmdline-opts/fail-early.d +++ b/extern/curl/docs/cmdline-opts/fail-early.d @@ -1,6 +1,9 @@ Long: fail-early Help: Fail on first transfer error, do not continue Added: 7.52.0 +Category: curl +Example: --fail-early $URL https://two.example +See-also: fail fail-with-body --- Fail and exit on the first detected transfer error. diff --git a/extern/curl/docs/cmdline-opts/fail-with-body.d b/extern/curl/docs/cmdline-opts/fail-with-body.d new file mode 100644 index 0000000000..9b8c7db4ef --- /dev/null +++ b/extern/curl/docs/cmdline-opts/fail-with-body.d @@ -0,0 +1,16 @@ +Long: fail-with-body +Protocols: HTTP +Help: Fail on HTTP errors but save the body +Category: http output +Added: 7.76.0 +See-also: fail +Example: --fail-with-body $URL +--- +Return an error on server errors where the HTTP response code is 400 or +greater). In normal cases when an HTTP server fails to deliver a document, it +returns an HTML document stating so (which often also describes why and +more). This flag will still allow curl to output and save that content but +also to return error 22. + +This is an alternative option to --fail which makes curl fail for the same +circumstances but without saving the content. diff --git a/extern/curl/docs/cmdline-opts/fail.d b/extern/curl/docs/cmdline-opts/fail.d index c46c571bfe..e7a9f9aec1 100644 --- a/extern/curl/docs/cmdline-opts/fail.d +++ b/extern/curl/docs/cmdline-opts/fail.d @@ -1,13 +1,17 @@ Long: fail Short: f Protocols: HTTP -Help: Fail silently (no output at all) on HTTP errors +Help: Fail fast with no output on HTTP errors +See-also: fail-with-body +Category: important http +Example: --fail $URL +Added: 4.0 --- -Fail silently (no output at all) on server errors. This is mostly done to -better enable scripts etc to better deal with failed attempts. In normal cases -when an HTTP server fails to deliver a document, it returns an HTML document -stating so (which often also describes why and more). This flag will prevent -curl from outputting that and return error 22. +Fail fast with no output at all on server errors. This is useful to enable +scripts and users to better deal with failed attempts. In normal cases when an +HTTP server fails to deliver a document, it returns an HTML document stating +so (which often also describes why and more). This flag will prevent curl from +outputting that and return error 22. This method is not fail-safe and there are occasions where non-successful response codes will slip through, especially when authentication is involved diff --git a/extern/curl/docs/cmdline-opts/false-start.d b/extern/curl/docs/cmdline-opts/false-start.d index 65a8afb8f3..4fe4eaa7ba 100644 --- a/extern/curl/docs/cmdline-opts/false-start.d +++ b/extern/curl/docs/cmdline-opts/false-start.d @@ -2,6 +2,9 @@ Long: false-start Help: Enable TLS False Start Protocols: TLS Added: 7.42.0 +Category: tls +Example: --false-start $URL +See-also: tcp-fastopen --- Tells curl to use false start during the TLS handshake. False start is a mode where a TLS client will start sending application data before verifying the diff --git a/extern/curl/docs/cmdline-opts/form-escape.d b/extern/curl/docs/cmdline-opts/form-escape.d new file mode 100644 index 0000000000..5fcd9ac1d0 --- /dev/null +++ b/extern/curl/docs/cmdline-opts/form-escape.d @@ -0,0 +1,10 @@ +Long: form-escape +Help: Escape multipart form field/file names using backslash +Protocols: HTTP +See-also: form +Added: 7.81.0 +Category: http post +Example: --form-escape --form 'field\\name=curl' 'file=@load"this' $URL +--- +Tells curl to pass on names of multipart form fields and files using +backslash-escaping instead of percent-encoding. diff --git a/extern/curl/docs/cmdline-opts/form-string.d b/extern/curl/docs/cmdline-opts/form-string.d index 49d0d44ef8..4b5b0d64c1 100644 --- a/extern/curl/docs/cmdline-opts/form-string.d +++ b/extern/curl/docs/cmdline-opts/form-string.d @@ -3,6 +3,9 @@ Help: Specify multipart MIME data Protocols: HTTP SMTP IMAP Arg: See-also: form +Category: http upload +Example: --form-string "data" $URL +Added: 7.13.2 --- Similar to --form except that the value string for the named parameter is used literally. Leading \&'@' and \&'<' characters, and the \&';type=' string in diff --git a/extern/curl/docs/cmdline-opts/form.d b/extern/curl/docs/cmdline-opts/form.d index 7f1aa31c3b..12012daa66 100644 --- a/extern/curl/docs/cmdline-opts/form.d +++ b/extern/curl/docs/cmdline-opts/form.d @@ -4,12 +4,16 @@ Arg: Help: Specify multipart MIME data Protocols: HTTP SMTP IMAP Mutexed: data head upload-file +Category: http upload +Example: --form "name=curl" --form "file=@loadthis" $URL +Added: 5.0 +See-also: data form-string form-escape --- For HTTP protocol family, this lets curl emulate a filled-in form in which a user has pressed the submit button. This causes curl to POST data using the Content-Type multipart/form-data according to RFC 2388. -For SMTP and IMAP protocols, this is the mean to compose a multipart mail +For SMTP and IMAP protocols, this is the means to compose a multipart mail message to transmit. This enables uploading of binary files etc. To force the 'content' part to be @@ -22,7 +26,7 @@ file. Tell curl to read content from stdin instead of a file by using - as filename. This goes for both @ and < constructs. When stdin is used, the contents is buffered in memory first by curl to determine its size and allow a -possible resend. Defining a part's data from a named non-regular file (such +possible resend. Defining a part's data from a named non-regular file (such as a named pipe or similar) is unfortunately not subject to buffering and will be effectively read at transmission time; since the full size is unknown before the transfer starts, such data is sent as chunks by HTTP and rejected @@ -58,11 +62,11 @@ filename=, like this: If filename/path contains ',' or ';', it must be quoted by double-quotes like: - curl -F "file=@\\"localfile\\";filename=\\"nameinpost\\"" example.com + curl -F "file=@\\"local,file\\";filename=\\"name;in;post\\"" example.com or - curl -F 'file=@"localfile";filename="nameinpost"' example.com + curl -F 'file=@"local,file";filename="name;in;post"' example.com Note that if a filename/path is quoted by double-quotes, any double-quote or backslash within the filename must be escaped by backslash. @@ -88,16 +92,12 @@ carriage-returns and trailing spaces are stripped. Here is an example of a header file contents: # This file contain two headers. -.br X-header-1: this is a header # The following header is folded. -.br X-header-2: this is -.br another header - To support sending multipart mail messages, the syntax is extended as follows: .br - name can be omitted: the equal sign is the first character of the argument, @@ -107,30 +107,26 @@ followed by a content type specification. .br - a multipart can be terminated with a '=)' argument. -Example: the following command sends an SMTP mime e-mail consisting in an +Example: the following command sends an SMTP mime email consisting in an inline part in two alternative formats: plain text and HTML. It attaches a text file: curl -F '=(;type=multipart/alternative' \\ -.br - -F '=plain text message' \\ -.br - -F '= HTML message;type=text/html' \\ -.br + -F '=plain text message' \\ + -F '= HTML message;type=text/html' \\ -F '=)' -F '=@textfile.txt' ... smtp://example.com Data can be encoded for transfer using encoder=. Available encodings are -\fIbinary\fP and \fI8bit\fP that do nothing else than adding the corresponding -Content-Transfer-Encoding header, \fI7bit\fP that only rejects 8-bit characters -with a transfer error, \fIquoted-printable\fP and \fIbase64\fP that encodes -data according to the corresponding schemes, limiting lines length to -76 characters. +*binary* and *8bit* that do nothing else than adding the corresponding +Content-Transfer-Encoding header, *7bit* that only rejects 8-bit characters +with a transfer error, *quoted-printable* and *base64* that encodes data +according to the corresponding schemes, limiting lines length to 76 +characters. Example: send multipart mail with a quoted-printable text message and a base64 attached file: curl -F '=text message;encoder=quoted-printable' \\ -.br -F '=@localfile;encoder=base64' ... smtp://example.com See further examples and details in the MANUAL. diff --git a/extern/curl/docs/cmdline-opts/ftp-account.d b/extern/curl/docs/cmdline-opts/ftp-account.d index 013c4f37b2..e47b44cb4e 100644 --- a/extern/curl/docs/cmdline-opts/ftp-account.d +++ b/extern/curl/docs/cmdline-opts/ftp-account.d @@ -3,6 +3,9 @@ Arg: Help: Account data string Protocols: FTP Added: 7.13.0 +Category: ftp auth +Example: --ftp-account "mr.robot" ftp://example.com/ +See-also: user --- When an FTP server asks for "account data" after user name and password has been provided, this data is sent off using the ACCT command. diff --git a/extern/curl/docs/cmdline-opts/ftp-alternative-to-user.d b/extern/curl/docs/cmdline-opts/ftp-alternative-to-user.d index 8982ba8b85..fdf3b417ae 100644 --- a/extern/curl/docs/cmdline-opts/ftp-alternative-to-user.d +++ b/extern/curl/docs/cmdline-opts/ftp-alternative-to-user.d @@ -3,6 +3,9 @@ Arg: Help: String to replace USER [name] Protocols: FTP Added: 7.15.5 +Category: ftp +Example: --ftp-alternative-to-user "U53r" ftp://example.com +See-also: ftp-account user --- If authenticating with the USER and PASS commands fails, send this command. When connecting to Tumbleweed's Secure Transport server over FTPS using a diff --git a/extern/curl/docs/cmdline-opts/ftp-create-dirs.d b/extern/curl/docs/cmdline-opts/ftp-create-dirs.d index ede57100d1..9b8595011d 100644 --- a/extern/curl/docs/cmdline-opts/ftp-create-dirs.d +++ b/extern/curl/docs/cmdline-opts/ftp-create-dirs.d @@ -2,7 +2,10 @@ Long: ftp-create-dirs Protocols: FTP SFTP Help: Create the remote dirs if not present See-also: create-dirs +Category: ftp sftp curl +Example: --ftp-create-dirs -T file ftp://example.com/remote/path/file +Added: 7.10.7 --- -When an FTP or SFTP URL/operation uses a path that doesn't currently exist on +When an FTP or SFTP URL/operation uses a path that does not currently exist on the server, the standard behavior of curl is to fail. Using this option, curl will instead attempt to create missing directories. diff --git a/extern/curl/docs/cmdline-opts/ftp-method.d b/extern/curl/docs/cmdline-opts/ftp-method.d index 95aa522e82..0d69356c69 100644 --- a/extern/curl/docs/cmdline-opts/ftp-method.d +++ b/extern/curl/docs/cmdline-opts/ftp-method.d @@ -3,13 +3,18 @@ Arg: Help: Control CWD usage Protocols: FTP Added: 7.15.1 +Category: ftp +Example: --ftp-method multicwd ftp://example.com/dir1/dir2/file +Example: --ftp-method nocwd ftp://example.com/dir1/dir2/file +Example: --ftp-method singlecwd ftp://example.com/dir1/dir2/file +See-also: list-only --- Control what method curl should use to reach a file on an FTP(S) server. The method argument should be one of the following alternatives: .RS .IP multicwd curl does a single CWD operation for each path part in the given URL. For deep -hierarchies this means very many commands. This is how RFC 1738 says it should +hierarchies this means many commands. This is how RFC 1738 says it should be done. This is the default but the slowest behavior. .IP nocwd curl does no CWD at all. curl will do SIZE, RETR, STOR etc and give a full diff --git a/extern/curl/docs/cmdline-opts/ftp-pasv.d b/extern/curl/docs/cmdline-opts/ftp-pasv.d index 44103e21a3..8c6c9799f1 100644 --- a/extern/curl/docs/cmdline-opts/ftp-pasv.d +++ b/extern/curl/docs/cmdline-opts/ftp-pasv.d @@ -3,13 +3,15 @@ Help: Use PASV/EPSV instead of PORT Protocols: FTP Added: 7.11.0 See-also: disable-epsv +Category: ftp +Example: --ftp-pasv ftp://example.com/ --- Use passive mode for the data connection. Passive is the internal default behavior, but using this option can be used to override a previous --ftp-port option. If this option is used several times, only the first one is used. Undoing an -enforced passive really isn't doable but you must then instead enforce the +enforced passive really is not doable but you must then instead enforce the correct --ftp-port again. Passive mode means that curl will try the EPSV command first and then PASV, diff --git a/extern/curl/docs/cmdline-opts/ftp-port.d b/extern/curl/docs/cmdline-opts/ftp-port.d index e4b1456082..cb6ab2a938 100644 --- a/extern/curl/docs/cmdline-opts/ftp-port.d +++ b/extern/curl/docs/cmdline-opts/ftp-port.d @@ -4,6 +4,11 @@ Help: Use PORT instead of PASV Short: P Protocols: FTP See-also: ftp-pasv disable-eprt +Category: ftp +Example: -P - ftp:/example.com +Example: -P eth0 ftp:/example.com +Example: -P 192.168.0.2 ftp:/example.com +Added: 4.0 --- Reverses the default initiator/listener roles when connecting with FTP. This option makes curl use active mode. curl then tells the server to connect back @@ -26,7 +31,8 @@ If this option is used several times, the last one will be used. Disable the use of PORT with --ftp-pasv. Disable the attempt to use the EPRT command instead of PORT by using --disable-eprt. EPRT is really PORT++. -Since 7.19.5, you can append \&":[start]-[end]\&" to the right of the address, -to tell curl what TCP port range to use. That means you specify a port range, -from a lower to a higher number. A single number works as well, but do note -that it increases the risk of failure since the port may not be available. +You can also append \&":[start]-[end]\&" to the right of the address, to tell +curl what TCP port range to use. That means you specify a port range, from a +lower to a higher number. A single number works as well, but do note that it +increases the risk of failure since the port may not be available. +(Added in 7.19.5) diff --git a/extern/curl/docs/cmdline-opts/ftp-pret.d b/extern/curl/docs/cmdline-opts/ftp-pret.d index dac4c35319..8d9d7749c5 100644 --- a/extern/curl/docs/cmdline-opts/ftp-pret.d +++ b/extern/curl/docs/cmdline-opts/ftp-pret.d @@ -2,6 +2,9 @@ Long: ftp-pret Help: Send PRET before PASV Protocols: FTP Added: 7.20.0 +Category: ftp +Example: --ftp-pret ftp://example.com/ +See-also: ftp-port ftp-pasv --- Tell curl to send a PRET command before PASV (and EPSV). Certain FTP servers, mainly drftpd, require this non-standard command for directory listings as diff --git a/extern/curl/docs/cmdline-opts/ftp-skip-pasv-ip.d b/extern/curl/docs/cmdline-opts/ftp-skip-pasv-ip.d index da6ab11fc7..36f9e6da13 100644 --- a/extern/curl/docs/cmdline-opts/ftp-skip-pasv-ip.d +++ b/extern/curl/docs/cmdline-opts/ftp-skip-pasv-ip.d @@ -3,10 +3,14 @@ Help: Skip the IP address for PASV Protocols: FTP Added: 7.14.2 See-also: ftp-pasv +Category: ftp +Example: --ftp-skip-pasv-ip ftp://example.com/ --- Tell curl to not use the IP address the server suggests in its response to curl's PASV command when curl connects the data connection. Instead curl will re-use the same IP address it already uses for the control connection. +Since curl 7.74.0 this option is enabled by default. + This option has no effect if PORT, EPRT or EPSV is used instead of PASV. diff --git a/extern/curl/docs/cmdline-opts/ftp-ssl-ccc-mode.d b/extern/curl/docs/cmdline-opts/ftp-ssl-ccc-mode.d index be10294985..15ad1f54b0 100644 --- a/extern/curl/docs/cmdline-opts/ftp-ssl-ccc-mode.d +++ b/extern/curl/docs/cmdline-opts/ftp-ssl-ccc-mode.d @@ -4,6 +4,8 @@ Help: Set CCC mode Protocols: FTP Added: 7.16.2 See-also: ftp-ssl-ccc +Category: ftp tls +Example: --ftp-ssl-ccc-mode active --ftp-ssl-ccc ftps://example.com/ --- Sets the CCC mode. The passive mode will not initiate the shutdown, but instead wait for the server to do it, and will not reply to the shutdown from diff --git a/extern/curl/docs/cmdline-opts/ftp-ssl-ccc.d b/extern/curl/docs/cmdline-opts/ftp-ssl-ccc.d index c6edc5b395..bfaf431bbb 100644 --- a/extern/curl/docs/cmdline-opts/ftp-ssl-ccc.d +++ b/extern/curl/docs/cmdline-opts/ftp-ssl-ccc.d @@ -3,6 +3,8 @@ Help: Send CCC after authenticating Protocols: FTP See-also: ssl ftp-ssl-ccc-mode Added: 7.16.1 +Category: ftp tls +Example: --ftp-ssl-ccc ftps://example.com/ --- Use CCC (Clear Command Channel) Shuts down the SSL/TLS layer after authenticating. The rest of the control channel communication will be diff --git a/extern/curl/docs/cmdline-opts/ftp-ssl-control.d b/extern/curl/docs/cmdline-opts/ftp-ssl-control.d index 87a822531d..7221b996bc 100644 --- a/extern/curl/docs/cmdline-opts/ftp-ssl-control.d +++ b/extern/curl/docs/cmdline-opts/ftp-ssl-control.d @@ -2,7 +2,10 @@ Long: ftp-ssl-control Help: Require SSL/TLS for FTP login, clear for transfer Protocols: FTP Added: 7.16.0 +Category: ftp tls +Example: --ftp-ssl-control ftp://example.com +See-also: ssl --- Require SSL/TLS for the FTP login, clear for transfer. Allows secure authentication, but non-encrypted data transfers for efficiency. Fails the -transfer if the server doesn't support SSL/TLS. +transfer if the server does not support SSL/TLS. diff --git a/extern/curl/docs/cmdline-opts/gen.pl b/extern/curl/docs/cmdline-opts/gen.pl index a921298a64..2418526cfe 100755 --- a/extern/curl/docs/cmdline-opts/gen.pl +++ b/extern/curl/docs/cmdline-opts/gen.pl @@ -1,10 +1,31 @@ #!/usr/bin/env perl +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2022, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### =begin comment This script generates the manpage. -Example: gen.pl mainpage > curl.1 +Example: gen.pl [files] > curl.1 Dev notes: @@ -16,18 +37,27 @@ =end comment =cut -my $some_dir=$ARGV[1] || "."; - -opendir(my $dh, $some_dir) || die "Can't opendir $some_dir: $!"; -my @s = grep { /\.d$/ && -f "$some_dir/$_" } readdir($dh); -closedir $dh; - my %optshort; my %optlong; my %helplong; my %arglong; my %redirlong; my %protolong; +my %catlong; + +use POSIX qw(strftime); +my $date = strftime "%B %d %Y", localtime; +my $year = strftime "%Y", localtime; +my $version = "unknown"; + +open(INC, "<../../include/curl/curlver.h"); +while() { + if($_ =~ /^#define LIBCURL_VERSION \"([0-9.]*)/) { + $version = $1; + last; + } +} +close(INC); # get the long name version, return the man page string sub manpageify { @@ -46,16 +76,47 @@ sub manpageify { sub printdesc { my @desc = @_; + my $exam = 0; for my $d (@desc) { + if($d =~ /\(Added in ([0-9.]+)\)/i) { + my $ver = $1; + if(too_old($ver)) { + $d =~ s/ *\(Added in $ver\)//gi; + } + } + if($d !~ /^.\\"/) { + # **bold** + $d =~ s/\*\*([^ ]*)\*\*/\\fB$1\\fP/g; + # *italics* + $d =~ s/\*([^ ]*)\*/\\fI$1\\fP/g; + } + if(!$exam && ($d =~ /^ /)) { + # start of example + $exam = 1; + print ".nf\n"; # no-fill + } + elsif($exam && ($d !~ /^ /)) { + # end of example + $exam = 0; + print ".fi\n"; # fill-in + } # skip lines starting with space (examples) if($d =~ /^[^ ]/) { for my $k (keys %optlong) { my $l = manpageify($k); - $d =~ s/--$k([^a-z0-9_-])/$l$1/; + $d =~ s/--$k([^a-z0-9_-])(\W)/$l$1$2/; } } + # quote "bare" minuses in the output + $d =~ s/( |\\fI|^)--/$1\\-\\-/g; + $d =~ s/([ -]|\\fI|^)-/$1\\-/g; + # handle single quotes first on the line + $d =~ s/(\s*)\'/$1\\(aq/; print $d; } + if($exam) { + print ".fi\n"; # fill-in + } } sub seealso { @@ -89,8 +150,29 @@ sub protocols { } } +sub too_old { + my ($version)=@_; + my $a = 999999; + if($version =~ /^(\d+)\.(\d+)\.(\d+)/) { + $a = $1 * 1000 + $2 * 10 + $3; + } + elsif($version =~ /^(\d+)\.(\d+)/) { + $a = $1 * 1000 + $2 * 10; + } + if($a < 7300) { + # we consider everything before 7.30.0 to be too old to mention + # specific changes for + return 1; + } + return 0; +} + sub added { my ($standalone, $data)=@_; + if(too_old($data)) { + # don't mention ancient additions + return ""; + } if($standalone) { return ".SH \"ADDED\"\nAdded in curl version $data\n"; } @@ -101,7 +183,7 @@ sub added { sub single { my ($f, $standalone)=@_; - open(F, "<:crlf", "$some_dir/$f") || + open(F, "<:crlf", "$f") || return 1; my $short; my $long; @@ -111,9 +193,13 @@ sub single { my $arg; my $mutexed; my $requires; + my $category; my $seealso; + my @examples; # there can be more than one my $magic; # cmdline special option + my $line; while() { + $line++; if(/^Short: *(.)/i) { $short=$1; } @@ -144,12 +230,35 @@ sub single { elsif(/^Requires: *(.*)/i) { $requires=$1; } + elsif(/^Category: *(.*)/i) { + $category=$1; + } + elsif(/^Example: *(.*)/i) { + push @examples, $1; + } elsif(/^Help: *(.*)/i) { ; } elsif(/^---/) { if(!$long) { - print STDERR "WARN: no 'Long:' in $f\n"; + print STDERR "ERROR: no 'Long:' in $f\n"; + return 1; + } + if(!$category) { + print STDERR "ERROR: no 'Category:' in $f\n"; + return 2; + } + if(!$examples[0]) { + print STDERR "$f:$line:1:ERROR: no 'Example:' present\n"; + return 2; + } + if(!$added) { + print STDERR "$f:$line:1:ERROR: no 'Added:' version present\n"; + return 2; + } + if(!$seealso) { + print STDERR "$f:$line:1:ERROR: no 'See-also:' field present\n"; + return 2; } last; } @@ -178,6 +287,9 @@ sub single { $opt .= " $arg"; } + # quote "bare" minuses in opt + $opt =~ s/( |^)--/$1\\-\\-/g; + $opt =~ s/( |^)-/$1\\-/g; if($standalone) { print ".TH curl 1 \"30 Nov 2016\" \"curl 7.52.0\" \"curl manual\"\n"; print ".SH OPTION\n"; @@ -201,12 +313,24 @@ sub single { if($seealso) { my @m=split(/ /, $seealso); my $mstr; + my $and = 0; + my $num = scalar(@m); + if($num > 2) { + # use commas up to this point + $and = $num - 1; + } + my $i = 0; for my $k (@m) { if(!$helplong{$k}) { - print STDERR "WARN: $f see-alsos a non-existing option: $k\n"; + print STDERR "$f:$line:1:WARN: see-also a non-existing option: $k\n"; } my $l = manpageify($k); - $mstr .= sprintf "%s$l", $mstr?" and ":""; + my $sep = " and"; + if($and && ($i < $and)) { + $sep = ","; + } + $mstr .= sprintf "%s$l", $mstr?"$sep ":""; + $i++; } push @foot, seealso($standalone, $mstr); } @@ -225,7 +349,18 @@ sub single { my $l = manpageify($k); $mstr .= sprintf "%s$l", $mstr?" and ":""; } - push @foot, overrides($standalone, "This option overrides $mstr. "); + push @foot, overrides($standalone, + "This option is mutually exclusive to $mstr. "); + } + if($examples[0]) { + my $s =""; + $s="s" if($examples[1]); + print "\nExample$s:\n.nf\n"; + foreach my $e (@examples) { + $e =~ s!\$URL!https://example.com!g; + print " curl $e\n"; + } + print ".fi\n"; } if($added) { push @foot, added($standalone, $added); @@ -241,12 +376,13 @@ sub single { sub getshortlong { my ($f)=@_; - open(F, "<:crlf", "$some_dir/$f"); + open(F, "<:crlf", "$f"); my $short; my $long; my $help; my $arg; my $protocols; + my $category; while() { if(/^Short: (.)/i) { $short=$1; @@ -263,6 +399,9 @@ sub getshortlong { elsif(/^Protocols: (.*)/i) { $protocols=$1; } + elsif(/^Category: (.*)/i) { + $category=$1; + } elsif(/^---/) { last; } @@ -276,20 +415,24 @@ sub getshortlong { $helplong{$long}=$help; $arglong{$long}=$arg; $protolong{$long}=$protocols; + $catlong{$long}=$category; } } sub indexoptions { - foreach my $f (@s) { - getshortlong($f); - } + my (@files) = @_; + foreach my $f (@files) { + getshortlong($f); + } } sub header { my ($f)=@_; - open(F, "<:crlf", "$some_dir/$f"); + open(F, "<:crlf", "$f"); my @d; while() { + s/%DATE/$date/g; + s/%VERSION/$version/g; push @d, $_; } close(F); @@ -297,9 +440,47 @@ sub header { } sub listhelp { + print <, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#include "tool_setup.h" +#include "tool_help.h" + +/* + * DO NOT edit tool_listhelp.c manually. + * This source file is generated with the following command: + + cd \$srcroot/docs/cmdline-opts + ./gen.pl listhelp *.d > \$srcroot/src/tool_listhelp.c + */ + +const struct helptxt helptext[] = { +HEAD + ; foreach my $f (sort keys %helplong) { my $long = $f; my $short = $optlong{$long}; + my @categories = split ' ', $catlong{$long}; + my $bitmask; my $opt; if(defined($short) && $long) { @@ -308,7 +489,13 @@ sub listhelp { elsif($long && !$short) { $opt = " --$long"; } - + for my $i (0 .. $#categories) { + $bitmask .= 'CURLHELP_' . uc $categories[$i]; + # If not last element, append | + if($i < $#categories) { + $bitmask .= ' | '; + } + } my $arg = $arglong{$long}; if($arg) { $opt .= " $arg"; @@ -316,25 +503,55 @@ sub listhelp { my $desc = $helplong{$f}; $desc =~ s/\"/\\\"/g; # escape double quotes - my $line = sprintf " {\"%s\",\n \"%s\"},\n", $opt, $desc; + my $line = sprintf " {\"%s\",\n \"%s\",\n %s},\n", $opt, $desc, $bitmask; - if(length($opt) + length($desc) > 78) { - print STDERR "WARN: the --$long line is too long\n"; + if(length($opt) > 78) { + print STDERR "WARN: the --$long name is too long\n"; + } + elsif(length($desc) > 78) { + print STDERR "WARN: the --$long description is too long\n"; } print $line; } + print < [srcdir]\n"; + print "Usage: gen.pl [files]\n"; } #------------------------------------------------------------------------ +my $cmd = shift @ARGV; +my @files = @ARGV; # the rest are the files + # learn all existing options -indexoptions(); +indexoptions(@files); -getargs(); +getargs($cmd, @files); diff --git a/extern/curl/docs/cmdline-opts/get.d b/extern/curl/docs/cmdline-opts/get.d index be7cb25f0c..3920d686cf 100644 --- a/extern/curl/docs/cmdline-opts/get.d +++ b/extern/curl/docs/cmdline-opts/get.d @@ -1,6 +1,12 @@ Long: get Short: G Help: Put the post data in the URL and use GET +Category: http upload +Example: --get $URL +Example: --get -d "tool=curl" -d "age=old" $URL +Example: --get -I -d "tool=curl" $URL +Added: 7.8.1 +See-also: data request --- When used, this option will make all data specified with --data, --data-binary or --data-urlencode to be used in an HTTP GET request instead of the POST @@ -11,5 +17,5 @@ If used in combination with --head, the POST data will instead be appended to the URL with a HEAD request. If this option is used several times, only the first one is used. This is -because undoing a GET doesn't make sense, but you should then instead enforce +because undoing a GET does not make sense, but you should then instead enforce the alternative method you prefer. diff --git a/extern/curl/docs/cmdline-opts/globoff.d b/extern/curl/docs/cmdline-opts/globoff.d index fff6516b6d..7660c8b718 100644 --- a/extern/curl/docs/cmdline-opts/globoff.d +++ b/extern/curl/docs/cmdline-opts/globoff.d @@ -1,8 +1,12 @@ Long: globoff Short: g Help: Disable URL sequences and ranges using {} and [] +Category: curl +Example: -g "https://example.com/{[]}}}}" +Added: 7.6 +See-also: config disable --- This option switches off the "URL globbing parser". When you set this option, -you can specify URLs that contain the letters {}[] without having them being -interpreted by curl itself. Note that these letters are not normal legal URL -contents but they should be encoded according to the URI standard. +you can specify URLs that contain the letters {}[] without having curl itself +interpret them. Note that these letters are not normal legal URL contents but +they should be encoded according to the URI standard. diff --git a/extern/curl/docs/cmdline-opts/happy-eyeballs-timeout-ms.d b/extern/curl/docs/cmdline-opts/happy-eyeballs-timeout-ms.d index ec9a8c228f..6897a69a55 100644 --- a/extern/curl/docs/cmdline-opts/happy-eyeballs-timeout-ms.d +++ b/extern/curl/docs/cmdline-opts/happy-eyeballs-timeout-ms.d @@ -1,13 +1,16 @@ Long: happy-eyeballs-timeout-ms Arg: -Help: How long to wait in milliseconds for IPv6 before trying IPv4 +Help: Time for IPv6 before trying IPv4 Added: 7.59.0 +Category: connection +Example: --happy-eyeballs-timeout-ms 500 $URL +See-also: max-time connect-timeout --- -Happy eyeballs is an algorithm that attempts to connect to both IPv4 and IPv6 -addresses for dual-stack hosts, preferring IPv6 first for the number of -milliseconds. If the IPv6 address cannot be connected to within that time then -a connection attempt is made to the IPv4 address in parallel. The first -connection to be established is the one that is used. +Happy Eyeballs is an algorithm that attempts to connect to both IPv4 and IPv6 +addresses for dual-stack hosts, giving IPv6 a head-start of the specified +number of milliseconds. If the IPv6 address cannot be connected to within that +time, then a connection attempt is made to the IPv4 address in parallel. The +first connection to be established is the one that is used. The range of suggested useful values is limited. Happy Eyeballs RFC 6555 says "It is RECOMMENDED that connection attempts be paced 150-250 ms apart to diff --git a/extern/curl/docs/cmdline-opts/haproxy-protocol.d b/extern/curl/docs/cmdline-opts/haproxy-protocol.d index cc41c9c447..792db6766b 100644 --- a/extern/curl/docs/cmdline-opts/haproxy-protocol.d +++ b/extern/curl/docs/cmdline-opts/haproxy-protocol.d @@ -2,10 +2,13 @@ Long: haproxy-protocol Help: Send HAProxy PROXY protocol v1 header Protocols: HTTP Added: 7.60.0 +Category: http proxy +Example: --haproxy-protocol $URL +See-also: proxy --- -Send a HAProxy PROXY protocol v1 header at the beginning of the connection. This -is used by some load balancers and reverse proxies to indicate the client's -true IP address and port. +Send a HAProxy PROXY protocol v1 header at the beginning of the +connection. This is used by some load balancers and reverse proxies to +indicate the client's true IP address and port. This option is primarily useful when sending test requests to a service that expects this header. diff --git a/extern/curl/docs/cmdline-opts/head.d b/extern/curl/docs/cmdline-opts/head.d index 350a100f65..c659337ff6 100644 --- a/extern/curl/docs/cmdline-opts/head.d +++ b/extern/curl/docs/cmdline-opts/head.d @@ -2,6 +2,10 @@ Long: head Short: I Help: Show document info only Protocols: HTTP FTP FILE +Category: http ftp file +Example: -I $URL +Added: 4.0 +See-also: get verbose trace-ascii --- Fetch the headers only! HTTP-servers feature the command HEAD which this uses to get nothing but the header of a document. When used on an FTP or FILE file, diff --git a/extern/curl/docs/cmdline-opts/header.d b/extern/curl/docs/cmdline-opts/header.d index d8292ed775..59a97a6653 100644 --- a/extern/curl/docs/cmdline-opts/header.d +++ b/extern/curl/docs/cmdline-opts/header.d @@ -3,37 +3,40 @@ Short: H Arg:
Help: Pass custom header(s) to server Protocols: HTTP +Category: http +See-also: user-agent referer +Example: -H "X-First-Name: Joe" $URL +Example: -H "User-Agent: yes-please/2000" $URL +Example: -H "Host:" $URL +Added: 5.0 --- Extra header to include in the request when sending HTTP to a server. You may specify any number of extra headers. Note that if you should add a custom header that has the same name as one of the internal ones curl would use, your externally set header will be used instead of the internal one. This allows you to make even trickier stuff than curl would normally do. You should not -replace internally set headers without knowing perfectly well what you're +replace internally set headers without knowing perfectly well what you are doing. Remove an internal header by giving a replacement without content on the right side of the colon, as in: -H \&"Host:". If you send the custom header with no-value then its header must be terminated with a semicolon, such as \-H \&"X-Custom-Header;" to send "X-Custom-Header:". curl will make sure that each header you add/replace is sent with the proper -end-of-line marker, you should thus \fBnot\fP add that as a part of the header -content: do not add newlines or carriage returns, they will only mess things up -for you. +end-of-line marker, you should thus **not** add that as a part of the header +content: do not add newlines or carriage returns, they will only mess things +up for you. -Starting in 7.55.0, this option can take an argument in @filename style, which -then adds a header for each line in the input file. Using @- will make curl -read the header file from stdin. +This option can take an argument in @filename style, which then adds a header +for each line in the input file. Using @- will make curl read the header file +from stdin. Added in 7.55.0. -See also the --user-agent and --referer options. +You need --proxy-header to send custom headers intended for an HTTP +proxy. Added in 7.37.0. -Starting in 7.37.0, you need --proxy-header to send custom headers intended -for a proxy. +Passing on a "Transfer-Encoding: chunked" header when doing an HTTP request +with a request body, will make curl send the data using chunked encoding. -Example: - - curl -H "X-First-Name: Joe" http://example.com/ - -\fBWARNING\fP: headers set with this option will be set in all requests - even +**WARNING**: headers set with this option will be set in all requests - even after redirects are followed, like when told with --location. This can lead to the header being sent to other hosts than the original host, so sensitive headers should be used with caution combined with following redirects. diff --git a/extern/curl/docs/cmdline-opts/help.d b/extern/curl/docs/cmdline-opts/help.d index 64aa696d47..664c040a83 100644 --- a/extern/curl/docs/cmdline-opts/help.d +++ b/extern/curl/docs/cmdline-opts/help.d @@ -1,6 +1,15 @@ Long: help +Arg: Short: h -Help: This help text +Help: Get help for commands +Category: important curl +Example: --help all +Added: 4.0 +See-also: verbose --- -Usage help. This lists all current command line options with a short -description. +Usage help. This lists all commands of the . +If no arg was provided, curl will display the most important +command line arguments. +If the argument "all" was provided, curl will display all options available. +If the argument "category" was provided, curl will display all categories and +their meanings. diff --git a/extern/curl/docs/cmdline-opts/hostpubmd5.d b/extern/curl/docs/cmdline-opts/hostpubmd5.d index a851158031..d3ea6b6f40 100644 --- a/extern/curl/docs/cmdline-opts/hostpubmd5.d +++ b/extern/curl/docs/cmdline-opts/hostpubmd5.d @@ -3,6 +3,9 @@ Arg: Help: Acceptable MD5 hash of the host public key Protocols: SFTP SCP Added: 7.17.1 +Category: sftp scp +Example: --hostpubmd5 e5c1c49020640a5ab0f2034854c321a8 sftp://example.com/ +See-also: hostpubsha256 --- Pass a string containing 32 hexadecimal digits. The string should be the 128 bit MD5 checksum of the remote host's public key, curl will refuse diff --git a/extern/curl/docs/cmdline-opts/hostpubsha256.d b/extern/curl/docs/cmdline-opts/hostpubsha256.d new file mode 100644 index 0000000000..2330d1a364 --- /dev/null +++ b/extern/curl/docs/cmdline-opts/hostpubsha256.d @@ -0,0 +1,12 @@ +Long: hostpubsha256 +Arg: +Help: Acceptable SHA256 hash of the host public key +Protocols: SFTP SCP +Added: 7.80.0 +Category: sftp scp +Example: --hostpubsha256 NDVkMTQxMGQ1ODdmMjQ3MjczYjAyOTY5MmRkMjVmNDQ= sftp://example.com/ +See-also: hostpubmd5 +--- +Pass a string containing a Base64-encoded SHA256 hash of the remote +host's public key. Curl will refuse the connection with the host +unless the hashes match. diff --git a/extern/curl/docs/cmdline-opts/hsts.d b/extern/curl/docs/cmdline-opts/hsts.d new file mode 100644 index 0000000000..65526f050a --- /dev/null +++ b/extern/curl/docs/cmdline-opts/hsts.d @@ -0,0 +1,18 @@ +Long: hsts +Arg: +Protocols: HTTPS +Help: Enable HSTS with this cache file +Added: 7.74.0 +Category: http +Example: --hsts cache.txt $URL +See-also: proto +--- +This option enables HSTS for the transfer. If the file name points to an +existing HSTS cache file, that will be used. After a completed transfer, the +cache will be saved to the file name again if it has been modified. + +Specify a "" file name (zero length) to avoid loading/saving and make curl +just handle HSTS in memory. + +If this option is used several times, curl will load contents from all the +files but the last one will be used for saving. diff --git a/extern/curl/docs/cmdline-opts/http0.9.d b/extern/curl/docs/cmdline-opts/http0.9.d index 7e783f696b..5797b2d7d6 100644 --- a/extern/curl/docs/cmdline-opts/http0.9.d +++ b/extern/curl/docs/cmdline-opts/http0.9.d @@ -1,8 +1,11 @@ Long: http0.9 Tags: Versions Protocols: HTTP -Added: Help: Allow HTTP 0.9 responses +Category: http +Example: --http0.9 $URL +Added: 7.64.0 +See-also: http1.1 http2 http3 --- Tells curl to be fine with HTTP version 0.9 response. diff --git a/extern/curl/docs/cmdline-opts/http1.0.d b/extern/curl/docs/cmdline-opts/http1.0.d index d9bbd76f0f..2cf70e551f 100644 --- a/extern/curl/docs/cmdline-opts/http1.0.d +++ b/extern/curl/docs/cmdline-opts/http1.0.d @@ -2,9 +2,12 @@ Short: 0 Long: http1.0 Tags: Versions Protocols: HTTP -Added: -Mutexed: http1.1 http2 +Added: 7.9.1 +Mutexed: http1.1 http2 http2-prior-knowledge http3 Help: Use HTTP 1.0 +Category: http +Example: --http1.0 $URL +See-also: http0.9 http1.1 --- Tells curl to use HTTP version 1.0 instead of using its internally preferred HTTP version. diff --git a/extern/curl/docs/cmdline-opts/http1.1.d b/extern/curl/docs/cmdline-opts/http1.1.d index f1e6b5c3bc..27b7e37734 100644 --- a/extern/curl/docs/cmdline-opts/http1.1.d +++ b/extern/curl/docs/cmdline-opts/http1.1.d @@ -2,7 +2,10 @@ Long: http1.1 Tags: Versions Protocols: HTTP Added: 7.33.0 -Mutexed: http1.0 http2 +Mutexed: http1.0 http2 http2-prior-knowledge http3 Help: Use HTTP 1.1 +Category: http +Example: --http1.1 $URL +See-also: http1.0 http0.9 --- Tells curl to use HTTP version 1.1. diff --git a/extern/curl/docs/cmdline-opts/http2-prior-knowledge.d b/extern/curl/docs/cmdline-opts/http2-prior-knowledge.d index f793f775dd..71821637ae 100644 --- a/extern/curl/docs/cmdline-opts/http2-prior-knowledge.d +++ b/extern/curl/docs/cmdline-opts/http2-prior-knowledge.d @@ -2,9 +2,12 @@ Long: http2-prior-knowledge Tags: Versions Protocols: HTTP Added: 7.49.0 -Mutexed: http1.1 http1.0 http2 +Mutexed: http1.1 http1.0 http2 http3 Requires: HTTP/2 Help: Use HTTP 2 without HTTP/1.1 Upgrade +Category: http +Example: --http2-prior-knowledge $URL +See-also: http2 http3 --- Tells curl to issue its non-TLS HTTP requests using HTTP/2 without HTTP/1.1 Upgrade. It requires prior knowledge that the server supports HTTP/2 straight diff --git a/extern/curl/docs/cmdline-opts/http2.d b/extern/curl/docs/cmdline-opts/http2.d index cf8f2988e6..f060575083 100644 --- a/extern/curl/docs/cmdline-opts/http2.d +++ b/extern/curl/docs/cmdline-opts/http2.d @@ -2,10 +2,22 @@ Long: http2 Tags: Versions Protocols: HTTP Added: 7.33.0 -Mutexed: http1.1 http1.0 http2-prior-knowledge +Mutexed: http1.1 http1.0 http2-prior-knowledge http3 Requires: HTTP/2 See-also: no-alpn Help: Use HTTP 2 See-also: http1.1 http3 +Category: http +Example: --http2 $URL --- Tells curl to use HTTP version 2. + +For HTTPS, this means curl will attempt to negotiate HTTP/2 in the TLS +handshake. curl does this by default. + +For HTTP, this means curl will attempt to upgrade the request to HTTP/2 using +the Upgrade: request header. + +When curl uses HTTP/2 over HTTPS, it does not itself insist on TLS 1.2 or +higher even though that is required by the specification. A user can add this +version requirement with --tlsv1.2. diff --git a/extern/curl/docs/cmdline-opts/http3.d b/extern/curl/docs/cmdline-opts/http3.d index 8265937a3d..f6c92b39a6 100644 --- a/extern/curl/docs/cmdline-opts/http3.d +++ b/extern/curl/docs/cmdline-opts/http3.d @@ -6,13 +6,14 @@ Mutexed: http1.1 http1.0 http2 http2-prior-knowledge Requires: HTTP/3 Help: Use HTTP v3 See-also: http1.1 http2 +Category: http +Example: --http3 $URL --- - -WARNING: this option is experimental. Do not use in production. +**WARNING**: this option is experimental. Do not use in production. Tells curl to use HTTP version 3 directly to the host and port number used in the URL. A normal HTTP/3 transaction will be done to a host and then get -redirected via Alt-SVc, but this option allows a user to circumvent that when +redirected via Alt-Svc, but this option allows a user to circumvent that when you know that the target speaks HTTP/3 on the given host and port. This option will make curl fail if a QUIC connection cannot be established, it diff --git a/extern/curl/docs/cmdline-opts/ignore-content-length.d b/extern/curl/docs/cmdline-opts/ignore-content-length.d index 53524f5184..4844ecafd6 100644 --- a/extern/curl/docs/cmdline-opts/ignore-content-length.d +++ b/extern/curl/docs/cmdline-opts/ignore-content-length.d @@ -1,6 +1,10 @@ Long: ignore-content-length Help: Ignore the size of the remote resource Protocols: FTP HTTP +Category: http ftp +Example: --ignore-content-length $URL +Added: 7.14.1 +See-also: ftp-skip-pasv-ip --- For HTTP, Ignore the Content-Length header. This is particularly useful for servers running Apache 1.x, which will report incorrect Content-Length for @@ -8,3 +12,5 @@ files larger than 2 gigabytes. For FTP (since 7.46.0), skip the RETR command to figure out the size before downloading a file. + +This option does not work for HTTP if libcurl was built to use hyper. diff --git a/extern/curl/docs/cmdline-opts/include.d b/extern/curl/docs/cmdline-opts/include.d index 9d282dd162..85831f845c 100644 --- a/extern/curl/docs/cmdline-opts/include.d +++ b/extern/curl/docs/cmdline-opts/include.d @@ -2,6 +2,9 @@ Long: include Short: i Help: Include protocol response headers in the output See-also: verbose +Category: important verbose +Example: -i $URL +Added: 4.8 --- Include the HTTP response headers in the output. The HTTP response headers can include things like server name, cookies, date of the document, HTTP version diff --git a/extern/curl/docs/cmdline-opts/insecure.d b/extern/curl/docs/cmdline-opts/insecure.d index 49b0a43228..90c1c0802a 100644 --- a/extern/curl/docs/cmdline-opts/insecure.d +++ b/extern/curl/docs/cmdline-opts/insecure.d @@ -1,16 +1,25 @@ Long: insecure Short: k -Help: Allow insecure server connections when using SSL -Protocols: TLS -See-also: proxy-insecure cacert +Help: Allow insecure server connections +Protocols: TLS SFTP SCP +See-also: proxy-insecure cacert capath +Category: tls sftp scp +Example: --insecure $URL +Added: 7.10 --- +By default, every secure connection curl makes is verified to be secure before +the transfer takes place. This option makes curl skip the verification step +and proceed without checking. -By default, every SSL connection curl makes is verified to be secure. This -option allows curl to proceed and operate even for server connections -otherwise considered insecure. +When this option is not used for protocols using TLS, curl verifies the +server's TLS certificate before it continues: that the certificate contains +the right name which matches the host name used in the URL and that the +certificate has been signed by a CA certificate present in the cert store. +See this online resource for further details: + https://curl.se/docs/sslcerts.html -The server connection is verified by making sure the server's certificate -contains the right name and verifies successfully using the cert store. +For SFTP and SCP, this option makes curl skip the *known_hosts* verification. +*known_hosts* is a file normally stored in the user's home directory in the +\&.ssh subdirectory, which contains host names and their public keys. -See this online resource for further details: - https://curl.haxx.se/docs/sslcerts.html +**WARNING**: using this option makes the transfer insecure. diff --git a/extern/curl/docs/cmdline-opts/interface.d b/extern/curl/docs/cmdline-opts/interface.d index 65827fb8be..fb21ea2f12 100644 --- a/extern/curl/docs/cmdline-opts/interface.d +++ b/extern/curl/docs/cmdline-opts/interface.d @@ -2,8 +2,10 @@ Long: interface Arg: Help: Use network INTERFACE (or address) See-also: dns-interface +Category: connection +Example: --interface eth0 $URL +Added: 7.3 --- - Perform an operation using a specified interface. You can enter interface name, IP address or host name. An example could look like: diff --git a/extern/curl/docs/cmdline-opts/ipv4.d b/extern/curl/docs/cmdline-opts/ipv4.d index 9c40c8c3ee..356d6e8269 100644 --- a/extern/curl/docs/cmdline-opts/ipv4.d +++ b/extern/curl/docs/cmdline-opts/ipv4.d @@ -2,11 +2,13 @@ Short: 4 Long: ipv4 Tags: Versions Protocols: -Added: +Added: 7.10.8 Mutexed: ipv6 Requires: See-also: http1.1 http2 Help: Resolve names to IPv4 addresses +Category: connection dns +Example: --ipv4 $URL --- -This option tells curl to resolve names to IPv4 addresses only, and not for -example try IPv6. +This option tells curl to use IPv4 addresses only, and not for example try +IPv6. diff --git a/extern/curl/docs/cmdline-opts/ipv6.d b/extern/curl/docs/cmdline-opts/ipv6.d index 6eef6dd03b..3a5b286bb8 100644 --- a/extern/curl/docs/cmdline-opts/ipv6.d +++ b/extern/curl/docs/cmdline-opts/ipv6.d @@ -2,11 +2,13 @@ Short: 6 Long: ipv6 Tags: Versions Protocols: -Added: +Added: 7.10.8 Mutexed: ipv4 Requires: See-also: http1.1 http2 Help: Resolve names to IPv6 addresses +Category: connection dns +Example: --ipv6 $URL --- -This option tells curl to resolve names to IPv6 addresses only, and not for -example try IPv4. +This option tells curl to use IPv6 addresses only, and not for example try +IPv4. diff --git a/extern/curl/docs/cmdline-opts/json.d b/extern/curl/docs/cmdline-opts/json.d new file mode 100644 index 0000000000..584b6ac9f6 --- /dev/null +++ b/extern/curl/docs/cmdline-opts/json.d @@ -0,0 +1,32 @@ +Long: json +Arg: +Help: HTTP POST JSON +Protocols: HTTP +See-also: data-binary data-raw +Mutexed: form head upload-file +Category: http post upload +Example: --json '{ "drink": "coffe" }' $URL +Example: --json '{ "drink":' --json ' "coffe" }' $URL +Example: --json @prepared $URL +Example: --json @- $URL < json.txt +Added: 7.82.0 +--- +Sends the specified JSON data in a POST request to the HTTP server. --json +works as a shortcut for passing on these three options: + + --data [arg] + --header "Content-Type: application/json" + --header "Accept: application/json" + +There is **no verification** that the passed in data is actual JSON or that +the syntax is correct. + +If you start the data with the letter @, the rest should be a file name to +read the data from, or a single dash (-) if you want curl to read the data +from stdin. Posting data from a file named \&'foobar' would thus be done with +--json @foobar and to instead read the data from stdin, use --json @-. + +If this option is used more than once on the same command line, the additional +data pieces will be concatenated to the previous before sending. + +The headers this option sets can be overridden with --header as usual. diff --git a/extern/curl/docs/cmdline-opts/junk-session-cookies.d b/extern/curl/docs/cmdline-opts/junk-session-cookies.d index 40ccd9c2df..cbc2692408 100644 --- a/extern/curl/docs/cmdline-opts/junk-session-cookies.d +++ b/extern/curl/docs/cmdline-opts/junk-session-cookies.d @@ -3,8 +3,11 @@ Short: j Help: Ignore session cookies read from file Protocols: HTTP See-also: cookie cookie-jar +Category: http +Example: --junk-session-cookies -b cookies.txt $URL +Added: 7.9.7 --- When curl is told to read cookies from a given file, this option will make it discard all "session cookies". This will basically have the same effect as if a new session is started. Typical browsers always discard session cookies when -they're closed down. +they are closed down. diff --git a/extern/curl/docs/cmdline-opts/keepalive-time.d b/extern/curl/docs/cmdline-opts/keepalive-time.d index c816e13ff0..4bd675033c 100644 --- a/extern/curl/docs/cmdline-opts/keepalive-time.d +++ b/extern/curl/docs/cmdline-opts/keepalive-time.d @@ -2,12 +2,18 @@ Long: keepalive-time Arg: Help: Interval time for keepalive probes Added: 7.18.0 +Category: connection +Example: --keepalive-time 20 $URL +See-also: no-keepalive max-time --- This option sets the time a connection needs to remain idle before sending keepalive probes and the time between individual keepalive probes. It is currently effective on operating systems offering the TCP_KEEPIDLE and -TCP_KEEPINTVL socket options (meaning Linux, recent AIX, HP-UX and more). This -option has no effect if --no-keepalive is used. +TCP_KEEPINTVL socket options (meaning Linux, recent AIX, HP-UX and more). +Keepalives are used by the TCP stack to detect broken networks on idle +connections. The number of missed keepalive probes before declaring the +connection down is OS dependent and is commonly 9 or 10. This option has no +effect if --no-keepalive is used. If this option is used several times, the last one will be used. If unspecified, the option defaults to 60 seconds. diff --git a/extern/curl/docs/cmdline-opts/key-type.d b/extern/curl/docs/cmdline-opts/key-type.d index bf39bcd357..7a073a803b 100644 --- a/extern/curl/docs/cmdline-opts/key-type.d +++ b/extern/curl/docs/cmdline-opts/key-type.d @@ -2,6 +2,10 @@ Long: key-type Arg: Help: Private key file type (DER/PEM/ENG) Protocols: TLS +Category: tls +Example: --key-type DER --key here $URL +Added: 7.9.3 +See-also: key --- Private key file type. Specify which type your --key provided private key is. DER, PEM, and ENG are supported. If not specified, PEM is assumed. diff --git a/extern/curl/docs/cmdline-opts/key.d b/extern/curl/docs/cmdline-opts/key.d index 855e2f7b6b..4dd072a159 100644 --- a/extern/curl/docs/cmdline-opts/key.d +++ b/extern/curl/docs/cmdline-opts/key.d @@ -2,6 +2,10 @@ Long: key Arg: Protocols: TLS SSH Help: Private key file name +Category: tls ssh +Example: --cert certificate --key here $URL +Added: 7.9.3 +See-also: key-type cert --- Private key file name. Allows you to provide your private key in this separate file. For SSH, if not specified, curl tries the following candidates in order: @@ -14,4 +18,9 @@ PKCS#11 URI. If a PKCS#11 URI is provided, then the --engine option will be set as "pkcs11" if none was provided and the --key-type option will be set as "ENG" if none was provided. +If curl is built against Secure Transport or Schannel then this option is +ignored for TLS protocols (HTTPS, etc). Those backends expect the private key +to be already present in the keychain or PKCS#12 file containing the +certificate. + If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/krb.d b/extern/curl/docs/cmdline-opts/krb.d index 19547af080..ad2d8f679b 100644 --- a/extern/curl/docs/cmdline-opts/krb.d +++ b/extern/curl/docs/cmdline-opts/krb.d @@ -3,6 +3,10 @@ Arg: Help: Enable Kerberos with security Protocols: FTP Requires: Kerberos +Category: ftp +Example: --krb clear ftp://example.com/ +Added: 7.3 +See-also: delegation ssl --- Enable Kerberos authentication and use. The level must be entered and should be one of 'clear', 'safe', 'confidential', or 'private'. Should you use a diff --git a/extern/curl/docs/cmdline-opts/libcurl.d b/extern/curl/docs/cmdline-opts/libcurl.d index ef132fe745..752eda31a1 100644 --- a/extern/curl/docs/cmdline-opts/libcurl.d +++ b/extern/curl/docs/cmdline-opts/libcurl.d @@ -2,10 +2,16 @@ Long: libcurl Arg: Help: Dump libcurl equivalent code of this command line Added: 7.16.1 +Category: curl +Example: --libcurl client.c $URL +See-also: verbose --- -Append this option to any ordinary curl command line, and you will get a +Append this option to any ordinary curl command line, and you will get libcurl-using C source code written to the file that does the equivalent of what your command-line operation does! +This option is global and does not need to be specified for each use of +--next. + If this option is used several times, the last given file name will be used. diff --git a/extern/curl/docs/cmdline-opts/limit-rate.d b/extern/curl/docs/cmdline-opts/limit-rate.d index 06c456e3e7..9594dfee21 100644 --- a/extern/curl/docs/cmdline-opts/limit-rate.d +++ b/extern/curl/docs/cmdline-opts/limit-rate.d @@ -1,15 +1,25 @@ Long: limit-rate Arg: Help: Limit transfer speed to RATE +Category: connection +Example: --limit-rate 100K $URL +Example: --limit-rate 1000 $URL +Example: --limit-rate 10M $URL +Added: 7.10 +See-also: speed-limit speed-time --- Specify the maximum transfer rate you want curl to use - for both downloads -and uploads. This feature is useful if you have a limited pipe and you'd like +and uploads. This feature is useful if you have a limited pipe and you would like your transfer not to use your entire bandwidth. To make it slower than it otherwise would be. The given speed is measured in bytes/second, unless a suffix is appended. Appending 'k' or 'K' will count the number as kilobytes, 'm' or 'M' makes it -megabytes, while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G. +megabytes, while 'g' or 'G' makes it gigabytes. The suffixes (k, M, G, T, P) +are 1024 based. For example 1k is 1024. Examples: 200K, 3m and 1G. + +The rate limiting logic works on averaging the transfer speed to no more than +the set threshold over a period of multiple seconds. If you also use the --speed-limit option, that option will take precedence and might cripple the rate-limiting slightly, to help keeping the speed-limit diff --git a/extern/curl/docs/cmdline-opts/list-only.d b/extern/curl/docs/cmdline-opts/list-only.d index 4c56304a0d..4fb2f6b9b2 100644 --- a/extern/curl/docs/cmdline-opts/list-only.d +++ b/extern/curl/docs/cmdline-opts/list-only.d @@ -2,13 +2,16 @@ Long: list-only Short: l Protocols: FTP POP3 Help: List only mode -Added: 7.21.5 +Added: 4.0 +Category: ftp pop3 +Example: --list-only ftp://example.com/dir/ +See-also: quote request --- (FTP) When listing an FTP directory, this switch forces a name-only view. This is especially useful if the user wants to machine-parse the contents of an FTP -directory since the normal directory view doesn't use a standard look or -format. When used like this, the option causes a NLST command to be sent to +directory since the normal directory view does not use a standard look or +format. When used like this, the option causes an NLST command to be sent to the server instead of LIST. Note: Some FTP servers list only files in their response to NLST; they do not @@ -17,8 +20,8 @@ include sub-directories and symbolic links. (POP3) When retrieving a specific email from POP3, this switch forces a LIST command to be performed instead of RETR. This is particularly useful if the user wants -to see if a specific message id exists on the server and what size it is. +to see if a specific message-id exists on the server and what size it is. -Note: When combined with --request, this option can be used to send an UIDL +Note: When combined with --request, this option can be used to send a UIDL command instead, so the user may use the email's unique identifier rather than -it's message id to make the request. +its message-id to make the request. diff --git a/extern/curl/docs/cmdline-opts/local-port.d b/extern/curl/docs/cmdline-opts/local-port.d index d96b46eb89..fd157d93c0 100644 --- a/extern/curl/docs/cmdline-opts/local-port.d +++ b/extern/curl/docs/cmdline-opts/local-port.d @@ -2,6 +2,9 @@ Long: local-port Arg: Help: Force use of RANGE for local port numbers Added: 7.15.2 +Category: connection +Example: --local-port 1000-3000 $URL +See-also: globoff --- Set a preferred single number or range (FROM-TO) of local port numbers to use for the connection(s). Note that port numbers by nature are a scarce resource diff --git a/extern/curl/docs/cmdline-opts/location-trusted.d b/extern/curl/docs/cmdline-opts/location-trusted.d index 995a8718aa..0277aa7b58 100644 --- a/extern/curl/docs/cmdline-opts/location-trusted.d +++ b/extern/curl/docs/cmdline-opts/location-trusted.d @@ -2,8 +2,11 @@ Long: location-trusted Help: Like --location, and send auth to other hosts Protocols: HTTP See-also: user +Category: http auth +Example: --location-trusted -u user:password $URL +Added: 7.10.4 --- Like --location, but will allow sending the name + password to all hosts that the site may redirect to. This may or may not introduce a security breach if -the site redirects you to a site to which you'll send your authentication info -(which is plaintext in the case of HTTP Basic authentication). +the site redirects you to a site to which you will send your authentication +info (which is plaintext in the case of HTTP Basic authentication). diff --git a/extern/curl/docs/cmdline-opts/location.d b/extern/curl/docs/cmdline-opts/location.d index b5ba1f4faa..e694dfad18 100644 --- a/extern/curl/docs/cmdline-opts/location.d +++ b/extern/curl/docs/cmdline-opts/location.d @@ -2,18 +2,22 @@ Long: location Short: L Help: Follow redirects Protocols: HTTP +Category: http +Example: -L $URL +Added: 4.9 +See-also: resolve alt-svc --- If the server reports that the requested page has moved to a different location (indicated with a Location: header and a 3XX response code), this option will make curl redo the request on the new place. If used together with --include or --head, headers from all requested pages will be shown. When authentication is used, curl only sends its credentials to the initial -host. If a redirect takes curl to a different host, it won't be able to +host. If a redirect takes curl to a different host, it will not be able to intercept the user+password. See also --location-trusted on how to change this. You can limit the amount of redirects to follow by using the --max-redirs option. -When curl follows a redirect and if the request is a POST, it will do the +When curl follows a redirect and if the request is a POST, it will send the following request with a GET if the HTTP response was 301, 302, or 303. If the response code was any other 3xx code, curl will re-send the following request using the same unmodified method. diff --git a/extern/curl/docs/cmdline-opts/login-options.d b/extern/curl/docs/cmdline-opts/login-options.d index 8bad0511d4..b524ebb0a7 100644 --- a/extern/curl/docs/cmdline-opts/login-options.d +++ b/extern/curl/docs/cmdline-opts/login-options.d @@ -1,14 +1,17 @@ Long: login-options Arg: -Protocols: IMAP POP3 SMTP +Protocols: IMAP LDAP POP3 SMTP Help: Server login options Added: 7.34.0 +Category: imap pop3 smtp auth +Example: --login-options 'AUTH=*' imap://example.com +See-also: user --- Specify the login options to use during server authentication. -You can use the login options to specify protocol specific options that may -be used during authentication. At present only IMAP, POP3 and SMTP support -login options. For more information about the login options please see -RFC 2384, RFC 5092 and IETF draft draft-earhart-url-smtp-00.txt +You can use login options to specify protocol specific options that may be +used during authentication. At present only IMAP, POP3 and SMTP support +login options. For more information about login options please see RFC +2384, RFC 5092 and IETF draft draft-earhart-url-smtp-00.txt If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/mail-auth.d b/extern/curl/docs/cmdline-opts/mail-auth.d index 70cf0eda46..49a02d5baa 100644 --- a/extern/curl/docs/cmdline-opts/mail-auth.d +++ b/extern/curl/docs/cmdline-opts/mail-auth.d @@ -4,6 +4,8 @@ Protocols: SMTP Help: Originator address of the original email Added: 7.25.0 See-also: mail-rcpt mail-from +Category: smtp +Example: --mail-auth user@example.come -T mail smtp://example.com/ --- Specify a single address. This will be used to specify the authentication address (identity) of a submitted message that is being relayed to another diff --git a/extern/curl/docs/cmdline-opts/mail-from.d b/extern/curl/docs/cmdline-opts/mail-from.d index 1d932344cf..be0547c9f2 100644 --- a/extern/curl/docs/cmdline-opts/mail-from.d +++ b/extern/curl/docs/cmdline-opts/mail-from.d @@ -4,5 +4,7 @@ Help: Mail from this address Protocols: SMTP Added: 7.20.0 See-also: mail-rcpt mail-auth +Category: smtp +Example: --mail-from user@example.com -T mail smtp://example.com/ --- Specify a single address that the given mail should get sent from. diff --git a/extern/curl/docs/cmdline-opts/mail-rcpt-allowfails.d b/extern/curl/docs/cmdline-opts/mail-rcpt-allowfails.d index b5723df346..12296afdc1 100644 --- a/extern/curl/docs/cmdline-opts/mail-rcpt-allowfails.d +++ b/extern/curl/docs/cmdline-opts/mail-rcpt-allowfails.d @@ -2,6 +2,9 @@ Long: mail-rcpt-allowfails Help: Allow RCPT TO command to fail for some recipients Protocols: SMTP Added: 7.69.0 +Category: smtp +Example: --mail-rcpt-allowfails --mail-rcpt dest@example.com smtp://example.com +See-also: mail-rcpt --- When sending data to multiple recipients, by default curl will abort SMTP conversation if at least one of the recipients causes RCPT TO command to @@ -11,5 +14,6 @@ The default behavior can be changed by passing --mail-rcpt-allowfails command-line option which will make curl ignore errors and proceed with the remaining valid recipients. -In case when all recipients cause RCPT TO command to fail, curl will abort SMTP -conversation and return the error received from to the last RCPT TO command. \ No newline at end of file +If all recipients trigger RCPT TO failures and this flag is specified, curl +will still abort the SMTP conversation and return the error received from to +the last RCPT TO command. diff --git a/extern/curl/docs/cmdline-opts/mail-rcpt.d b/extern/curl/docs/cmdline-opts/mail-rcpt.d index 0a2859b688..8a3b43c154 100644 --- a/extern/curl/docs/cmdline-opts/mail-rcpt.d +++ b/extern/curl/docs/cmdline-opts/mail-rcpt.d @@ -3,13 +3,13 @@ Arg:
Help: Mail to this address Protocols: SMTP Added: 7.20.0 +Category: smtp +Example: --mail-rcpt user@example.net smtp://example.com +See-also: mail-rcpt-allowfails --- -Specify a single address, user name or mailing list name. Repeat this +Specify a single email address, user name or mailing list name. Repeat this option several times to send to multiple recipients. -When performing a mail transfer, the recipient should specify a valid email -address to send the mail to. - When performing an address verification (VRFY command), the recipient should be specified as the user name or user name and domain (as per Section 3.5 of RFC5321). (Added in 7.34.0) diff --git a/extern/curl/docs/cmdline-opts/manual.d b/extern/curl/docs/cmdline-opts/manual.d index a9dbb0c78a..9674a465d3 100644 --- a/extern/curl/docs/cmdline-opts/manual.d +++ b/extern/curl/docs/cmdline-opts/manual.d @@ -1,5 +1,9 @@ Long: manual Short: M Help: Display the full manual +Category: curl +Example: --manual +Added: 5.2 +See-also: verbose libcurl trace --- Manual. Display the huge help text. diff --git a/extern/curl/docs/cmdline-opts/max-filesize.d b/extern/curl/docs/cmdline-opts/max-filesize.d index 50d5266e1b..9e3abca426 100644 --- a/extern/curl/docs/cmdline-opts/max-filesize.d +++ b/extern/curl/docs/cmdline-opts/max-filesize.d @@ -1,7 +1,11 @@ Long: max-filesize Arg: Help: Maximum file size to download +Protocols: FTP HTTP MQTT See-also: limit-rate +Category: connection +Example: --max-filesize 100K $URL +Added: 7.10.8 --- Specify the maximum size (in bytes) of a file to download. If the file requested is larger than this value, the transfer will not start and curl will @@ -11,6 +15,6 @@ A size modifier may be used. For example, Appending 'k' or 'K' will count the number as kilobytes, 'm' or 'M' makes it megabytes, while 'g' or 'G' makes it gigabytes. Examples: 200K, 3m and 1G. (Added in 7.58.0) -\fBNOTE:\fP The file size is not always known prior to download, and for such +**NOTE**: The file size is not always known prior to download, and for such files this option has no effect even if the file transfer ends up being larger -than this given limit. This concerns both FTP and HTTP transfers. +than this given limit. \ No newline at end of file diff --git a/extern/curl/docs/cmdline-opts/max-redirs.d b/extern/curl/docs/cmdline-opts/max-redirs.d index a97860a8bd..a0b549399d 100644 --- a/extern/curl/docs/cmdline-opts/max-redirs.d +++ b/extern/curl/docs/cmdline-opts/max-redirs.d @@ -2,9 +2,13 @@ Long: max-redirs Arg: Help: Maximum number of redirects allowed Protocols: HTTP +Category: http +Example: --max-redirs 3 --location $URL +Added: 7.5 +See-also: location --- -Set maximum number of redirection-followings allowed. When --location is used, -is used to prevent curl from following redirections too much. By default, the -limit is set to 50 redirections. Set this option to -1 to make it unlimited. +Set maximum number of redirections to follow. When --location is used, to +prevent curl from following too many redirects, by default, the limit is +set to 50 redirects. Set this option to -1 to make it unlimited. If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/max-time.d b/extern/curl/docs/cmdline-opts/max-time.d index 0057f9d047..7246f61349 100644 --- a/extern/curl/docs/cmdline-opts/max-time.d +++ b/extern/curl/docs/cmdline-opts/max-time.d @@ -1,8 +1,12 @@ Long: max-time Short: m -Arg: -Help: Maximum time allowed for the transfer +Arg: +Help: Maximum time allowed for transfer See-also: connect-timeout +Category: connection +Example: --max-time 10 $URL +Example: --max-time 2.92 $URL +Added: 4.0 --- Maximum time in seconds that you allow the whole operation to take. This is useful for preventing your batch jobs from hanging for hours due to slow diff --git a/extern/curl/docs/cmdline-opts/metalink.d b/extern/curl/docs/cmdline-opts/metalink.d index 81fc8bc78c..f1c0aeefe1 100644 --- a/extern/curl/docs/cmdline-opts/metalink.d +++ b/extern/curl/docs/cmdline-opts/metalink.d @@ -1,26 +1,9 @@ Long: metalink Help: Process given URLs as metalink XML file Added: 7.27.0 -Requires: metalink +Category: misc +Example: --metalink file $URL +See-also: parallel --- -This option can tell curl to parse and process a given URI as Metalink file -(both version 3 and 4 (RFC 5854) are supported) and make use of the mirrors -listed within for failover if there are errors (such as the file or server not -being available). It will also verify the hash of the file after the download -completes. The Metalink file itself is downloaded and processed in memory and -not stored in the local file system. - -Example to use a remote Metalink file: - - curl --metalink http://www.example.com/example.metalink - -To use a Metalink file in the local file system, use FILE protocol (file://): - - curl --metalink file://example.metalink - -Please note that if FILE protocol is disabled, there is no way to use a local -Metalink file at the time of this writing. Also note that if --metalink and ---include are used together, --include will be ignored. This is because -including headers in the response will break Metalink parser and if the -headers are included in the file described in Metalink file, hash check will -fail. +This option was previously used to specify a metalink resource. Metalink +support has been disabled in curl since 7.78.0 for security reasons. diff --git a/extern/curl/docs/cmdline-opts/negotiate.d b/extern/curl/docs/cmdline-opts/negotiate.d index 69a6b91709..69a0e6c661 100644 --- a/extern/curl/docs/cmdline-opts/negotiate.d +++ b/extern/curl/docs/cmdline-opts/negotiate.d @@ -2,6 +2,9 @@ Long: negotiate Help: Use HTTP Negotiate (SPNEGO) authentication Protocols: HTTP See-also: basic ntlm anyauth proxy-negotiate +Category: auth http +Example: --negotiate -u : $URL +Added: 7.10.6 --- Enables Negotiate (SPNEGO) authentication. @@ -10,6 +13,6 @@ This option requires a library built with GSS-API or SSPI support. Use When using this option, you must also provide a fake --user option to activate the authentication code properly. Sending a '-u :' is enough as the user name -and password from the --user option aren't actually used. +and password from the --user option are not actually used. If this option is used several times, only the first one is used. diff --git a/extern/curl/docs/cmdline-opts/netrc-file.d b/extern/curl/docs/cmdline-opts/netrc-file.d index 50126d2554..7af727fb14 100644 --- a/extern/curl/docs/cmdline-opts/netrc-file.d +++ b/extern/curl/docs/cmdline-opts/netrc-file.d @@ -3,9 +3,12 @@ Help: Specify FILE for netrc Arg: Added: 7.21.5 Mutexed: netrc +Category: curl +Example: --netrc-file netrc $URL +See-also: netrc user config --- This option is similar to --netrc, except that you provide the path (absolute -or relative) to the netrc file that curl should use. You can only specify one +or relative) to the netrc file that curl should use. You can only specify one netrc file per invocation. If several --netrc-file options are provided, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/netrc-optional.d b/extern/curl/docs/cmdline-opts/netrc-optional.d index c285403094..5f6fea626a 100644 --- a/extern/curl/docs/cmdline-opts/netrc-optional.d +++ b/extern/curl/docs/cmdline-opts/netrc-optional.d @@ -2,6 +2,9 @@ Long: netrc-optional Help: Use either .netrc or URL Mutexed: netrc See-also: netrc-file +Category: curl +Example: --netrc-optional $URL +Added: 7.9.8 --- -Very similar to --netrc, but this option makes the .netrc usage \fBoptional\fP +Similar to --netrc, but this option makes the .netrc usage **optional** and not mandatory as the --netrc option does. diff --git a/extern/curl/docs/cmdline-opts/netrc.d b/extern/curl/docs/cmdline-opts/netrc.d index 2df26782cc..02497f7809 100644 --- a/extern/curl/docs/cmdline-opts/netrc.d +++ b/extern/curl/docs/cmdline-opts/netrc.d @@ -1,17 +1,23 @@ Long: netrc Short: n Help: Must read .netrc for user name and password +Category: curl +Example: --netrc $URL +Added: 4.6 +See-also: netrc-file config user --- -Makes curl scan the \fI.netrc\fP (\fI_netrc\fP on Windows) file in the user's -home directory for login name and password. This is typically used for FTP on +Makes curl scan the *.netrc* (*_netrc* on Windows) file in the user's home +directory for login name and password. This is typically used for FTP on Unix. If used with HTTP, curl will enable user authentication. See -\fInetrc(5)\fP \fIftp(1)\fP for details on the file format. Curl will not -complain if that file doesn't have the right permissions (it should not be -either world- or group-readable). The environment variable "HOME" is used to -find the home directory. +*netrc(5)* and *ftp(1)* for details on the file format. Curl will not +complain if that file does not have the right permissions (it should be +neither world- nor group-readable). The environment variable "HOME" is used +to find the home directory. -A quick and very simple example of how to setup a \fI.netrc\fP to allow curl -to FTP to the machine host.domain.com with user name \&'myself' and password -\&'secret' should look similar to: +A quick and simple example of how to setup a *.netrc* to allow curl to FTP to +the machine host.domain.com with user name \&'myself' and password \&'secret' +could look similar to: -.B "machine host.domain.com login myself password secret" + machine host.domain.com + login myself + password secret" diff --git a/extern/curl/docs/cmdline-opts/next.d b/extern/curl/docs/cmdline-opts/next.d index 1d1e70a35c..a41ca69467 100644 --- a/extern/curl/docs/cmdline-opts/next.d +++ b/extern/curl/docs/cmdline-opts/next.d @@ -5,6 +5,10 @@ Protocols: Added: 7.36.0 Magic: divider Help: Make next URL use its separate set of options +Category: curl +Example: $URL --next -d postthis www2.example.com +Example: -I $URL --next https://example.net/ +See-also: parallel config --- Tells curl to use a separate operation for the following URL and associated options. This allows you to send several URL requests, each with their own diff --git a/extern/curl/docs/cmdline-opts/no-alpn.d b/extern/curl/docs/cmdline-opts/no-alpn.d index 88abb83682..bc62076323 100644 --- a/extern/curl/docs/cmdline-opts/no-alpn.d +++ b/extern/curl/docs/cmdline-opts/no-alpn.d @@ -5,6 +5,8 @@ Added: 7.36.0 See-also: no-npn http2 Requires: TLS Help: Disable the ALPN TLS extension +Category: tls http +Example: --no-alpn $URL --- Disable the ALPN TLS extension. ALPN is enabled by default if libcurl was built with an SSL library that supports ALPN. ALPN is used by a libcurl that supports diff --git a/extern/curl/docs/cmdline-opts/no-buffer.d b/extern/curl/docs/cmdline-opts/no-buffer.d index 65a6282f64..c356eb34d9 100644 --- a/extern/curl/docs/cmdline-opts/no-buffer.d +++ b/extern/curl/docs/cmdline-opts/no-buffer.d @@ -1,6 +1,10 @@ Long: no-buffer Short: N Help: Disable buffering of the output stream +Category: curl +Example: --no-buffer $URL +Added: 6.5 +See-also: progress-bar --- Disables the buffering of the output stream. In normal work situations, curl will use a standard buffered output stream that will have the effect that it diff --git a/extern/curl/docs/cmdline-opts/no-clobber.d b/extern/curl/docs/cmdline-opts/no-clobber.d new file mode 100644 index 0000000000..382e6786a2 --- /dev/null +++ b/extern/curl/docs/cmdline-opts/no-clobber.d @@ -0,0 +1,16 @@ +Long: no-clobber +Help: Do not overwrite files that already exist +Category: curl output +Added: 7.83.0 +See-also: output remote-name +Example: --no-clobber --output local/dir/file $URL +--- +When used in conjunction with the --output, --remote-header-name, +--remote-name, or --remote-name-all options, curl avoids overwriting files +that already exist. Instead, a dot and a number gets appended to the name +of the file that would be created, up to filename.100 after which it will not +create any file. + +Note that this is the negated option name documented. You can thus use +--clobber to enforce the clobbering, even if --remote-header-name or -J is +specified. diff --git a/extern/curl/docs/cmdline-opts/no-keepalive.d b/extern/curl/docs/cmdline-opts/no-keepalive.d index 8fb28a0365..d65a3bd215 100644 --- a/extern/curl/docs/cmdline-opts/no-keepalive.d +++ b/extern/curl/docs/cmdline-opts/no-keepalive.d @@ -1,5 +1,9 @@ Long: no-keepalive Help: Disable TCP keepalive on the connection +Category: connection +Example: --no-keepalive $URL +Added: 7.18.0 +See-also: keepalive-time --- Disables the use of keepalive messages on the TCP connection. curl otherwise enables them by default. diff --git a/extern/curl/docs/cmdline-opts/no-npn.d b/extern/curl/docs/cmdline-opts/no-npn.d index ab0f6de2e0..7a9239d361 100644 --- a/extern/curl/docs/cmdline-opts/no-npn.d +++ b/extern/curl/docs/cmdline-opts/no-npn.d @@ -6,6 +6,8 @@ Mutexed: See-also: no-alpn http2 Requires: TLS Help: Disable the NPN TLS extension +Category: tls http +Example: --no-npn $URL --- Disable the NPN TLS extension. NPN is enabled by default if libcurl was built with an SSL library that supports NPN. NPN is used by a libcurl that supports diff --git a/extern/curl/docs/cmdline-opts/no-progress-meter.d b/extern/curl/docs/cmdline-opts/no-progress-meter.d index aff0717d37..9c7413eeb9 100644 --- a/extern/curl/docs/cmdline-opts/no-progress-meter.d +++ b/extern/curl/docs/cmdline-opts/no-progress-meter.d @@ -2,6 +2,8 @@ Long: no-progress-meter Help: Do not show the progress meter See-also: verbose silent Added: 7.67.0 +Category: verbose +Example: --no-progress-meter -o store $URL --- Option to switch off the progress meter output without muting or otherwise affecting warning and informational messages like --silent does. diff --git a/extern/curl/docs/cmdline-opts/no-sessionid.d b/extern/curl/docs/cmdline-opts/no-sessionid.d index 397a158697..1b771857bf 100644 --- a/extern/curl/docs/cmdline-opts/no-sessionid.d +++ b/extern/curl/docs/cmdline-opts/no-sessionid.d @@ -2,8 +2,11 @@ Long: no-sessionid Help: Disable SSL session-ID reusing Protocols: TLS Added: 7.16.0 +Category: tls +Example: --no-sessionid $URL +See-also: insecure --- -Disable curl's use of SSL session-ID caching. By default all transfers are +Disable curl's use of SSL session-ID caching. By default all transfers are done using the cache. Note that while nothing should ever get hurt by attempting to reuse SSL session-IDs, there seem to be broken SSL implementations in the wild that may require you to disable this in order for diff --git a/extern/curl/docs/cmdline-opts/noproxy.d b/extern/curl/docs/cmdline-opts/noproxy.d index a216e75f49..0ed3907795 100644 --- a/extern/curl/docs/cmdline-opts/noproxy.d +++ b/extern/curl/docs/cmdline-opts/noproxy.d @@ -2,14 +2,17 @@ Long: noproxy Arg: Help: List of hosts which do not use proxy Added: 7.19.4 +Category: proxy +Example: --noproxy "www.example" $URL +See-also: proxy --- -Comma-separated list of hosts which do not use a proxy, if one is specified. -The only wildcard is a single * character, which matches all hosts, and -effectively disables the proxy. Each name in this list is matched as either -a domain which contains the hostname, or the hostname itself. For example, -local.com would match local.com, local.com:80, and www.local.com, but not -www.notlocal.com. +Comma-separated list of hosts for which not to use a proxy, if one is +specified. The only wildcard is a single * character, which matches all hosts, +and effectively disables the proxy. Each name in this list is matched as +either a domain which contains the hostname, or the hostname itself. For +example, local.com would match local.com, local.com:80, and www.local.com, but +not www.notlocal.com. Since 7.53.0, This option overrides the environment variables that disable the -proxy. If there's an environment variable disabling a proxy, you can set -noproxy list to \&"" to override it. +proxy ('no_proxy' and 'NO_PROXY'). If there's an environment variable +disabling a proxy, you can set the noproxy list to \&"" to override it. diff --git a/extern/curl/docs/cmdline-opts/ntlm-wb.d b/extern/curl/docs/cmdline-opts/ntlm-wb.d index 7b93384085..c8e72c325a 100644 --- a/extern/curl/docs/cmdline-opts/ntlm-wb.d +++ b/extern/curl/docs/cmdline-opts/ntlm-wb.d @@ -2,6 +2,9 @@ Long: ntlm-wb Help: Use HTTP NTLM authentication with winbind Protocols: HTTP See-also: ntlm proxy-ntlm +Category: auth http +Example: --ntlm-wb -u user:password $URL +Added: 7.22.0 --- Enables NTLM much in the style --ntlm does, but hand over the authentication to the separate binary ntlmauth application that is executed when needed. diff --git a/extern/curl/docs/cmdline-opts/ntlm.d b/extern/curl/docs/cmdline-opts/ntlm.d index baaa1d534d..658218a101 100644 --- a/extern/curl/docs/cmdline-opts/ntlm.d +++ b/extern/curl/docs/cmdline-opts/ntlm.d @@ -4,6 +4,9 @@ Mutexed: basic negotiate digest anyauth See-also: proxy-ntlm Protocols: HTTP Requires: TLS +Category: auth http +Example: --ntlm -u user:password $URL +Added: 7.10.6 --- Enables NTLM authentication. The NTLM authentication method was designed by Microsoft and is used by IIS web servers. It is a proprietary protocol, diff --git a/extern/curl/docs/cmdline-opts/oauth2-bearer.d b/extern/curl/docs/cmdline-opts/oauth2-bearer.d index 30466e579d..07bb54bde0 100644 --- a/extern/curl/docs/cmdline-opts/oauth2-bearer.d +++ b/extern/curl/docs/cmdline-opts/oauth2-bearer.d @@ -1,7 +1,11 @@ Long: oauth2-bearer Help: OAuth 2 Bearer Token Arg: -Protocols: IMAP POP3 SMTP HTTP +Protocols: IMAP LDAP POP3 SMTP HTTP +Category: auth +Example: --oauth2-bearer "mF_9.B5f-4.1JqM" $URL +Added: 7.33.0 +See-also: basic ntlm digest --- Specify the Bearer Token for OAUTH 2.0 server authentication. The Bearer Token is used in conjunction with the user name which can be specified as part of diff --git a/extern/curl/docs/cmdline-opts/output-dir.d b/extern/curl/docs/cmdline-opts/output-dir.d new file mode 100644 index 0000000000..230ebeea58 --- /dev/null +++ b/extern/curl/docs/cmdline-opts/output-dir.d @@ -0,0 +1,20 @@ +Long: output-dir +Arg: +Help: Directory to save files in +Added: 7.73.0 +See-also: remote-name remote-header-name +Category: curl +Example: --output-dir "tmp" -O $URL +--- + +This option specifies the directory in which files should be stored, when +--remote-name or --output are used. + +The given output directory is used for all URLs and output options on the +command line, up until the first --next. + +If the specified target directory does not exist, the operation will fail +unless --create-dirs is also used. + +If this option is used multiple times, the last specified directory will be +used. diff --git a/extern/curl/docs/cmdline-opts/output.d b/extern/curl/docs/cmdline-opts/output.d index 35f52a2130..15ddd525aa 100644 --- a/extern/curl/docs/cmdline-opts/output.d +++ b/extern/curl/docs/cmdline-opts/output.d @@ -3,17 +3,23 @@ Arg: Short: o Help: Write to file instead of stdout See-also: remote-name remote-name-all remote-header-name +Category: important curl +Example: -o file $URL +Example: "http://{one,two}.example.com" -o "file_#1.txt" +Example: "http://{site,host}.host[1-5].com" -o "#1_#2" +Example: -o file $URL -o file2 https://example.net +Added: 4.0 --- Write output to instead of stdout. If you are using {} or [] to fetch -multiple documents, you can use '#' followed by a number in the -specifier. That variable will be replaced with the current string for the URL -being fetched. Like in: +multiple documents, you should quote the URL and you can use '#' followed by a +number in the specifier. That variable will be replaced with the current +string for the URL being fetched. Like in: - curl http://{one,two}.example.com -o "file_#1.txt" + curl "http://{one,two}.example.com" -o "file_#1.txt" or use several variables like: - curl http://{site,host}.host[1-5].com -o "#1_#2" + curl "http://{site,host}.host[1-5].com" -o "#1_#2" You may use this option as many times as the number of URLs you have. For example, if you specify two URLs on the same command line, you can use it like @@ -21,7 +27,7 @@ this: curl -o aa example.com -o bb example.net -and the order of the -o options and the URLs doesn't matter, just that the +and the order of the -o options and the URLs does not matter, just that the first -o is for the first URL and so on, so the above command line can also be written as @@ -30,3 +36,11 @@ written as See also the --create-dirs option to create the local directories dynamically. Specifying the output as '-' (a single dash) will force the output to be done to stdout. + +To suppress response bodies, you can redirect output to /dev/null: + + curl example.com -o /dev/null + +Or for Windows use nul: + + curl example.com -o nul diff --git a/extern/curl/docs/cmdline-opts/page-footer b/extern/curl/docs/cmdline-opts/page-footer index defe7e8b28..4ba05cfc07 100644 --- a/extern/curl/docs/cmdline-opts/page-footer +++ b/extern/curl/docs/cmdline-opts/page-footer @@ -17,11 +17,11 @@ Sets the proxy server to use for HTTPS. .IP "[url-protocol]_PROXY [protocol://][:port]" Sets the proxy server to use for [url-protocol], where the protocol is a protocol that curl supports and as specified in a URL. FTP, FTPS, POP3, IMAP, -SMTP, LDAP etc. +SMTP, LDAP, etc. .IP "ALL_PROXY [protocol://][:port]" Sets the proxy server to use if no protocol-specific proxy is set. .IP "NO_PROXY " -list of host names that shouldn't go through any proxy. If set to an asterisk +list of host names that should not go through any proxy. If set to an asterisk \&'*' only, it matches all hosts. Each name in this list is matched as either a domain name which contains the hostname, or the hostname itself. @@ -37,18 +37,70 @@ accesses the target URL through the proxy. The list of host names can also be include numerical IP addresses, and IPv6 versions should then be given without enclosing brackets. +IPv6 numerical addresses are compared as strings, so they will only match if +the representations are the same: "::1" is the same as "::0:1" but they do not +match. +.IP "APPDATA " +On Windows, this variable is used when trying to find the home directory. If +the primary home variable are all unset. +.IP "COLUMNS " +If set, the specified number of characters will be used as the terminal width +when the alternative progress-bar is shown. If not set, curl will try to +figure it out using other ways. +.IP "CURL_CA_BUNDLE " +If set, will be used as the \fI--cacert\fP value. +.IP "CURL_HOME " +If set, is the first variable curl checks when trying to find its home +directory. If not set, it continues to check \fBXDG_CONFIG_HOME\fP. +.IP "CURL_SSL_BACKEND " +If curl was built with support for "MultiSSL", meaning that it has built-in +support for more than one TLS backend, this environment variable can be set to +the case insensitive name of the particular backend to use when curl is +invoked. Setting a name that is not a built-in alternative will make curl +stay with the default. + +SSL backend names (case-insensitive): bearssl, gnutls, gskit, mbedtls, +nss, openssl, rustls, schannel, secure-transport, wolfssl +.IP "HOME " +If set, this is used to find the home directory when that is needed. Like when +looking for the default .curlrc. \fBCURL_HOME\fP and \fBXDG_CONFIG_HOME\fP +have preference. +.IP "QLOGDIR " +If curl was built with HTTP/3 support, setting this environment variable to a +local directory will make curl produce qlogs in that directory, using file +names named after the destination connection id (in hex). Do note that these +files can become rather large. Works with both QUIC backends. +.IP SHELL +Used on VMS when trying to detect if using a DCL or a "unix" shell. +.IP "SSL_CERT_DIR " +If set, will be used as the \fI--capath\fP value. +.IP "SSL_CERT_FILE " +If set, will be used as the \fI--cacert\fP value. +.IP "SSLKEYLOGFILE " +If you set this environment variable to a file name, curl will store TLS +secrets from its connections in that file when invoked to enable you to +analyze the TLS traffic in real time using network analyzing tools such as +Wireshark. This works with the following TLS backends: OpenSSL, libressl, +BoringSSL, GnuTLS, NSS and wolfSSL. +.IP "USERPROFILE " +On Windows, this variable is used when trying to find the home directory. If +the other, primary, variable are all unset. If set, curl will use the path +"$USERPROFILE\\Application Data". +.IP "XDG_CONFIG_HOME " +If \fBCURL_HOME\fP is not set, this variable is checked when looking for a +default .curlrc file. .SH "PROXY PROTOCOL PREFIXES" -Since curl version 7.21.7, the proxy string may be specified with a -protocol:// prefix to specify alternative proxy protocols. +The proxy string may be specified with a protocol:// prefix to specify +alternative proxy protocols. (Added in 7.21.7) -If no protocol is specified in the proxy string or if the string doesn't match +If no protocol is specified in the proxy string or if the string does not match a supported one, the proxy will be treated as an HTTP proxy. The supported proxy protocol prefixes are as follows: .IP "http://" Makes it use it as an HTTP proxy. The default if no scheme prefix is used. .IP "https://" -Makes it treated as an \fBHTTPS\fP proxy. +Makes it treated as an **HTTPS** proxy. .IP "socks4://" Makes it the equivalent of --socks4 .IP "socks4a://" @@ -59,7 +111,7 @@ Makes it the equivalent of --socks5 Makes it the equivalent of --socks5-hostname .SH EXIT CODES There are a bunch of different error codes and their corresponding error -messages that may appear during bad conditions. At the time of this writing, +messages that may appear under error conditions. At the time of this writing, the exit codes are: .IP 1 Unsupported protocol. This build of curl has no support for this protocol. @@ -70,55 +122,55 @@ URL malformed. The syntax was not correct. .IP 4 A feature or option that was needed to perform the desired request was not enabled or was explicitly disabled at build-time. To make curl able to do -this, you probably need another build of libcurl! +this, you probably need another build of libcurl. .IP 5 -Couldn't resolve proxy. The given proxy host could not be resolved. +Could not resolve proxy. The given proxy host could not be resolved. .IP 6 -Couldn't resolve host. The given remote host was not resolved. +Could not resolve host. The given remote host could not be resolved. .IP 7 Failed to connect to host. .IP 8 -Weird server reply. The server sent data curl couldn't parse. +Weird server reply. The server sent data curl could not parse. .IP 9 FTP access denied. The server denied login or denied access to the particular resource or directory you wanted to reach. Most often you tried to change to a -directory that doesn't exist on the server. +directory that does not exist on the server. .IP 10 FTP accept failed. While waiting for the server to connect back when an active FTP session is used, an error code was sent over the control connection or similar. .IP 11 -FTP weird PASS reply. Curl couldn't parse the reply sent to the PASS request. +FTP weird PASS reply. Curl could not parse the reply sent to the PASS request. .IP 12 During an active FTP session while waiting for the server to connect back to curl, the timeout expired. .IP 13 -FTP weird PASV reply, Curl couldn't parse the reply sent to the PASV request. +FTP weird PASV reply, Curl could not parse the reply sent to the PASV request. .IP 14 -FTP weird 227 format. Curl couldn't parse the 227-line the server sent. +FTP weird 227 format. Curl could not parse the 227-line the server sent. .IP 15 -FTP can't get host. Couldn't resolve the host IP we got in the 227-line. +FTP cannot use host. Could not resolve the host IP we got in the 227-line. .IP 16 HTTP/2 error. A problem was detected in the HTTP2 framing layer. This is somewhat generic and can be one out of several problems, see the error message for details. .IP 17 -FTP couldn't set binary. Couldn't change transfer method to binary. +FTP could not set binary. Could not change transfer method to binary. .IP 18 Partial file. Only a part of the file was transferred. .IP 19 -FTP couldn't download/access the given file, the RETR (or similar) command +FTP could not download/access the given file, the RETR (or similar) command failed. .IP 21 FTP quote error. A quote command returned error from the server. .IP 22 -HTTP page not retrieved. The requested url was not found or returned another +HTTP page not retrieved. The requested URL was not found or returned another error with the HTTP error code being 400 or above. This return code only appears if --fail is used. .IP 23 -Write error. Curl couldn't write data to a local filesystem or similar. +Write error. Curl could not write data to a local filesystem or similar. .IP 25 -FTP couldn't STOR file. The server denied the STOR operation, used for FTP +FTP could not STOR file. The server denied the STOR operation, used for FTP uploading. .IP 26 Read error. Various reading problems. @@ -131,18 +183,18 @@ conditions. FTP PORT failed. The PORT command failed. Not all FTP servers support the PORT command, try doing a transfer using PASV instead! .IP 31 -FTP couldn't use REST. The REST command failed. This command is used for +FTP could not use REST. The REST command failed. This command is used for resumed FTP transfers. .IP 33 -HTTP range error. The range "command" didn't work. +HTTP range error. The range "command" did not work. .IP 34 HTTP post error. Internal post-request generation error. .IP 35 SSL connect error. The SSL handshaking failed. .IP 36 -Bad download resume. Couldn't continue an earlier aborted download. +Bad download resume. Could not continue an earlier aborted download. .IP 37 -FILE couldn't read file. Failed to open the file. Permissions? +FILE could not read file. Failed to open the file. Permissions? .IP 38 LDAP cannot bind. LDAP bind operation failed. .IP 39 @@ -166,7 +218,7 @@ Malformed telnet option. .IP 51 The peer's SSL certificate or SSH MD5 fingerprint was not OK. .IP 52 -The server didn't reply anything, which here is considered an error. +The server did not reply anything, which here is considered an error. .IP 53 SSL crypto engine not found. .IP 54 @@ -178,7 +230,7 @@ Failure in receiving network data. .IP 58 Problem with the local certificate. .IP 59 -Couldn't use specified SSL cipher. +Could not use specified SSL cipher. .IP 60 Peer certificate cannot be authenticated with known CA certificates. .IP 61 @@ -214,7 +266,7 @@ Character conversion failed. .IP 76 Character conversion functions required. .IP 77 -Problem with reading the SSL CA cert (path? access rights?). +Problem reading the SSL CA cert (path? access rights?). .IP 78 The resource referenced in the URL does not exist. .IP 79 @@ -226,31 +278,44 @@ Could not load CRL file, missing or wrong format (added in 7.19.0). .IP 83 Issuer check failed (added in 7.19.0). .IP 84 -The FTP PRET command failed +The FTP PRET command failed. .IP 85 -RTSP: mismatch of CSeq numbers +Mismatch of RTSP CSeq numbers. .IP 86 -RTSP: mismatch of Session Identifiers +Mismatch of RTSP Session Identifiers. .IP 87 -unable to parse FTP file list +Unable to parse FTP file list. .IP 88 -FTP chunk callback reported error +FTP chunk callback reported error. .IP 89 -No connection available, the session will be queued +No connection available, the session will be queued. .IP 90 -SSL public key does not matched pinned public key +SSL public key does not matched pinned public key. .IP 91 Invalid SSL certificate status. .IP 92 Stream error in HTTP/2 framing layer. +.IP 93 +An API function was called from inside a callback. +.IP 94 +An authentication function returned an error. +.IP 95 +A problem was detected in the HTTP/3 layer. This is somewhat generic and can +be one out of several problems, see the error message for details. +.IP 96 +QUIC connection error. This error may be caused by an SSL library error. QUIC +is the protocol used for HTTP/3 transfers. .IP XX More error codes will appear here in future releases. The existing ones are meant to never change. +.SH BUGS +If you experience any problems with curl, submit an issue in the project's bug +tracker on GitHub: https://github.com/curl/curl/issues .SH AUTHORS / CONTRIBUTORS Daniel Stenberg is the main author, but the whole list of contributors is found in the separate THANKS file. .SH WWW -https://curl.haxx.se +https://curl.se .SH "SEE ALSO" .BR ftp (1), .BR wget (1) diff --git a/extern/curl/docs/cmdline-opts/page-header b/extern/curl/docs/cmdline-opts/page-header index 51f45edadf..900d21d84e 100644 --- a/extern/curl/docs/cmdline-opts/page-header +++ b/extern/curl/docs/cmdline-opts/page-header @@ -5,11 +5,11 @@ .\" * | (__| |_| | _ <| |___ .\" * \___|\___/|_| \_\_____| .\" * -.\" * Copyright (C) 1998 - 2018, Daniel Stenberg, , et al. +.\" * Copyright (C) 1998 - 2021, Daniel Stenberg, , et al. .\" * .\" * This software is licensed as described in the file COPYING, which .\" * you should have received as part of this distribution. The terms -.\" * are also available at https://curl.haxx.se/docs/copyright.html. +.\" * are also available at https://curl.se/docs/copyright.html. .\" * .\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell .\" * copies of the Software, and permit persons to whom the Software is @@ -22,46 +22,46 @@ .\" .\" DO NOT EDIT. Generated by the curl project gen.pl man page generator. .\" -.TH curl 1 "16 Dec 2016" "Curl 7.52.0" "Curl Manual" +.TH curl 1 "%DATE" "curl %VERSION" "curl Manual" .SH NAME curl \- transfer a URL .SH SYNOPSIS .B curl [options / URLs] .SH DESCRIPTION -.B curl -is a tool to transfer data from or to a server, using one of the supported -protocols (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, -LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET -and TFTP). The command is designed to work without user interaction. +**curl** is a tool for transferring data from or to a server. It supports these +protocols: DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, +LDAP, LDAPS, MQTT, POP3, POP3S, RTMP, RTMPS, RTSP, SCP, SFTP, SMB, SMBS, SMTP, +SMTPS, TELNET or TFTP. The command is designed to work without user +interaction. curl offers a busload of useful tricks like proxy support, user authentication, FTP upload, HTTP post, SSL connections, cookies, file transfer -resume, Metalink, and more. As you will see below, the number of features will -make your head spin! +resume and more. As you will see below, the number of features will make your +head spin. curl is powered by libcurl for all transfer-related features. See -\fIlibcurl(3)\fP for details. +*libcurl(3)* for details. .SH URL -The URL syntax is protocol-dependent. You'll find a detailed description in +The URL syntax is protocol-dependent. You find a detailed description in RFC 3986. You can specify multiple URLs or parts of URLs by writing part sets within -braces as in: +braces and quoting the URL as in: - http://site.{one,two,three}.com + "http://site.{one,two,three}.com" or you can get sequences of alphanumeric series by using [] as in: - ftp://ftp.example.com/file[1-100].txt + "ftp://ftp.example.com/file[1-100].txt" - ftp://ftp.example.com/file[001-100].txt (with leading zeros) + "ftp://ftp.example.com/file[001-100].txt" (with leading zeros) - ftp://ftp.example.com/file[a-z].txt + "ftp://ftp.example.com/file[a-z].txt" Nested sequences are not supported, but you can use several ones next to each other: - http://example.com/archive[1996-1999]/vol[1-4]/part{a,b,c}.html + "http://example.com/archive[1996-1999]/vol[1-4]/part{a,b,c}.html" You can specify any amount of URLs on the command line. They will be fetched in a sequential manner in the specified order. You can specify command line @@ -70,9 +70,9 @@ options and URLs mixed and in any order on the command line. You can specify a step counter for the ranges to get every Nth number or letter: - http://example.com/file[1-100:10].txt + "http://example.com/file[1-100:10].txt" - http://example.com/file[a-z:2].txt + "http://example.com/file[a-z:2].txt" When using [] or {} sequences when invoked from a command line prompt, you probably have to put the full URL within double quotes to avoid the shell from @@ -82,7 +82,7 @@ for example '&', '?' and '*'. Provide the IPv6 zone index in the URL with an escaped percentage sign and the interface name. Like in - http://[fe80::3%25eth0]/ + "http://[fe80::3%25eth0]/" If you specify URL without protocol:// prefix, curl will attempt to guess what protocol you might want. It will then default to HTTP but try other protocols @@ -90,14 +90,72 @@ based on often-used host name prefixes. For example, for host names starting with "ftp." curl will assume you want to speak FTP. curl will do its best to use what you pass to it as a URL. It is not trying to -validate it as a syntactically correct URL by any means but is instead -\fBvery\fP liberal with what it accepts. +validate it as a syntactically correct URL by any means but is fairly liberal +with what it accepts. curl will attempt to re-use connections for multiple file transfers, so that getting many files from the same server will not do multiple connects / handshakes. This improves speed. Of course this is only done on files specified on a single command line and cannot be used between separate curl -invokes. +invocations. +.SH OUTPUT +If not told otherwise, curl writes the received data to stdout. It can be +instructed to instead save that data into a local file, using the --output or +--remote-name options. If curl is given multiple URLs to transfer on the +command line, it similarly needs multiple options for where to save them. + +curl does not parse or otherwise "understand" the content it gets or writes as +output. It does no encoding or decoding, unless explicitly asked to with +dedicated command line options. +.SH PROTOCOLS +curl supports numerous protocols, or put in URL terms: schemes. Your +particular build may not support them all. +.IP DICT +Lets you lookup words using online dictionaries. +.IP FILE +Read or write local files. curl does not support accessing file:// URL +remotely, but when running on Microsoft Windows using the native UNC approach +will work. +.IP FTP(S) +curl supports the File Transfer Protocol with a lot of tweaks and levers. With +or without using TLS. +.IP GOPHER(S) +Retrieve files. +.IP HTTP(S) +curl supports HTTP with numerous options and variations. It can speak HTTP +version 0.9, 1.0, 1.1, 2 and 3 depending on build options and the correct +command line options. +.IP IMAP(S) +Using the mail reading protocol, curl can "download" emails for you. With or +without using TLS. +.IP LDAP(S) +curl can do directory lookups for you, with or without TLS. +.IP MQTT +curl supports MQTT version 3. Downloading over MQTT equals "subscribe" to a +topic while uploading/posting equals "publish" on a topic. MQTT over TLS is +not supported (yet). +.IP POP3(S) +Downloading from a pop3 server means getting a mail. With or without using +TLS. +.IP RTMP(S) +The Realtime Messaging Protocol is primarily used to server streaming media +and curl can download it. +.IP RTSP +curl supports RTSP 1.0 downloads. +.IP SCP +curl supports SSH version 2 scp transfers. +.IP SFTP +curl supports SFTP (draft 5) done over SSH version 2. +.IP SMB(S) +curl supports SMB version 1 for upload and download. +.IP SMTP(S) +Uploading contents to an SMTP server means sending an email. With or without +TLS. +.IP TELNET +Telling curl to fetch a telnet URL starts an interactive session where it +sends what it reads on stdin and outputs what the server sends it. +.IP TFTP +curl can do TFTP downloads and uploads. .SH "PROGRESS METER" curl normally displays a progress meter during operations, indicating the amount of transferred data, transfer speeds and estimated time left, etc. The @@ -107,15 +165,15 @@ bytes. 1M is 1048576 bytes. curl displays this data to the terminal by default, so if you invoke curl to do an operation and it is about to write data to the terminal, it -\fIdisables\fP the progress meter as otherwise it would mess up the output +*disables* the progress meter as otherwise it would mess up the output mixing progress meter and response data. If you want a progress meter for HTTP POST or PUT requests, you need to redirect the response output to a file, using shell redirect (>), --output or similar. -It is not the same case for FTP upload as that operation does not spit out -any response data to the terminal. +This does not apply to FTP upload as that operation does not spit out any +response data to the terminal. If you prefer a progress "bar" instead of the regular meter, --progress-bar is your friend. You can also disable the progress meter completely with the @@ -129,13 +187,11 @@ or without a space between it and its value, although a space is a recommended separator. The long "double-dash" form, --data for example, requires a space between it and its value. -Short version options that don't need any additional values can be used +Short version options that do not need any additional values can be used immediately next to each other, like for example you can specify all the options -O, -L and -v at once as -OLv. -In general, all boolean options are enabled with --\fBoption\fP and yet again -disabled with --\fBno-\fPoption. That is, you use the exact same option name -but prefix it with "no-". However, in this list we mostly only list and show -the --option version of them. (This concept with --no options was added in -7.19.0. Previously most options were toggled on/off on repeated use of the -same command line option.) +In general, all boolean options are enabled with --**option** and yet again +disabled with --**no-**option. That is, you use the same option name but +prefix it with "no-". However, in this list we mostly only list and show the +--option version of them. diff --git a/extern/curl/docs/cmdline-opts/parallel-immediate.d b/extern/curl/docs/cmdline-opts/parallel-immediate.d index 343931085b..4f7468de65 100644 --- a/extern/curl/docs/cmdline-opts/parallel-immediate.d +++ b/extern/curl/docs/cmdline-opts/parallel-immediate.d @@ -2,8 +2,13 @@ Long: parallel-immediate Help: Do not wait for multiplexing (with --parallel) Added: 7.68.0 See-also: parallel parallel-max +Category: connection curl +Example: --parallel-immediate -Z $URL -o file1 $URL -o file2 --- When doing parallel transfers, this option will instruct curl that it should rather prefer opening up more connections in parallel at once rather than waiting to see if new transfers can be added as multiplexed streams on another connection. + +This option is global and does not need to be specified for each use of +--next. diff --git a/extern/curl/docs/cmdline-opts/parallel-max.d b/extern/curl/docs/cmdline-opts/parallel-max.d index a8c79c7433..1f22fcb7d2 100644 --- a/extern/curl/docs/cmdline-opts/parallel-max.d +++ b/extern/curl/docs/cmdline-opts/parallel-max.d @@ -1,9 +1,15 @@ Long: parallel-max +Arg: Help: Maximum concurrency for parallel transfers Added: 7.66.0 See-also: parallel +Category: connection curl +Example: --parallel-max 100 -Z $URL ftp://example.com/ --- When asked to do parallel transfers, using --parallel, this option controls the maximum amount of transfers to do simultaneously. +This option is global and does not need to be specified for each use of +--next. + The default is 50. diff --git a/extern/curl/docs/cmdline-opts/parallel.d b/extern/curl/docs/cmdline-opts/parallel.d index fac84e6243..f2ccaa78e6 100644 --- a/extern/curl/docs/cmdline-opts/parallel.d +++ b/extern/curl/docs/cmdline-opts/parallel.d @@ -2,6 +2,12 @@ Short: Z Long: parallel Help: Perform transfers in parallel Added: 7.66.0 +Category: connection curl +Example: --parallel $URL -o file1 $URL -o file2 +See-also: next verbose --- Makes curl perform its transfers in parallel as compared to the regular serial manner. + +This option is global and does not need to be specified for each use of +--next. diff --git a/extern/curl/docs/cmdline-opts/pass.d b/extern/curl/docs/cmdline-opts/pass.d index 2639cb9d06..621754d613 100644 --- a/extern/curl/docs/cmdline-opts/pass.d +++ b/extern/curl/docs/cmdline-opts/pass.d @@ -2,7 +2,11 @@ Long: pass Arg: Help: Pass phrase for the private key Protocols: SSH TLS +Category: ssh tls auth +Example: --pass secret --key file $URL +Added: 7.9.3 +See-also: key user --- -Passphrase for the private key +Passphrase for the private key. If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/path-as-is.d b/extern/curl/docs/cmdline-opts/path-as-is.d index 946e2f07a2..3a82c44099 100644 --- a/extern/curl/docs/cmdline-opts/path-as-is.d +++ b/extern/curl/docs/cmdline-opts/path-as-is.d @@ -1,6 +1,9 @@ Long: path-as-is Help: Do not squash .. sequences in URL path Added: 7.42.0 +Category: curl +Example: --path-as-is https://example.com/../../etc/passwd +See-also: request-target --- Tell curl to not handle sequences of /../ or /./ in the given URL path. Normally curl will squash or merge them according to standards but with diff --git a/extern/curl/docs/cmdline-opts/pinnedpubkey.d b/extern/curl/docs/cmdline-opts/pinnedpubkey.d index cd21911f85..b47c42a8fd 100644 --- a/extern/curl/docs/cmdline-opts/pinnedpubkey.d +++ b/extern/curl/docs/cmdline-opts/pinnedpubkey.d @@ -2,11 +2,16 @@ Long: pinnedpubkey Arg: Help: FILE/HASHES Public key to verify peer against Protocols: TLS +Category: tls +Example: --pinnedpubkey keyfile $URL +Example: --pinnedpubkey 'sha256//ce118b51897f4452dc' $URL +Added: 7.39.0 +See-also: hostpubsha256 --- Tells curl to use the specified public key file (or hashes) to verify the peer. This can be a path to a file which contains a single public key in PEM or DER format, or any number of base64 encoded sha256 hashes preceded by -\'sha256//\' and separated by \';\' +'sha256//' and separated by ';'. When negotiating a TLS or SSL connection, the server sends a certificate indicating its identity. A public key is extracted from this certificate and @@ -14,12 +19,19 @@ if it does not exactly match the public key provided to this option, curl will abort the connection before sending or receiving any data. PEM/DER support: - 7.39.0: OpenSSL, GnuTLS and GSKit - 7.43.0: NSS and wolfSSL - 7.47.0: mbedtls + +7.39.0: OpenSSL, GnuTLS and GSKit + +7.43.0: NSS and wolfSSL + +7.47.0: mbedtls + sha256 support: - 7.44.0: OpenSSL, GnuTLS, NSS and wolfSSL - 7.47.0: mbedtls + +7.44.0: OpenSSL, GnuTLS, NSS and wolfSSL + +7.47.0: mbedtls + Other SSL backends not supported. If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/post301.d b/extern/curl/docs/cmdline-opts/post301.d index 87a9fe7edc..744ef5813a 100644 --- a/extern/curl/docs/cmdline-opts/post301.d +++ b/extern/curl/docs/cmdline-opts/post301.d @@ -3,9 +3,11 @@ Help: Do not switch to GET after following a 301 Protocols: HTTP See-also: post302 post303 location Added: 7.17.1 +Category: http post +Example: --post301 --location -d "data" $URL --- Tells curl to respect RFC 7231/6.4.2 and not convert POST requests into GET -requests when following a 301 redirection. The non-RFC behaviour is ubiquitous +requests when following a 301 redirection. The non-RFC behavior is ubiquitous in web browsers, so curl does the conversion by default to maintain consistency. However, a server may require a POST to remain a POST after such a redirection. This option is meaningful only when using --location. diff --git a/extern/curl/docs/cmdline-opts/post302.d b/extern/curl/docs/cmdline-opts/post302.d index caf0d87f18..2c6d4b615c 100644 --- a/extern/curl/docs/cmdline-opts/post302.d +++ b/extern/curl/docs/cmdline-opts/post302.d @@ -3,9 +3,11 @@ Help: Do not switch to GET after following a 302 Protocols: HTTP See-also: post301 post303 location Added: 7.19.1 +Category: http post +Example: --post302 --location -d "data" $URL --- Tells curl to respect RFC 7231/6.4.3 and not convert POST requests into GET -requests when following a 302 redirection. The non-RFC behaviour is ubiquitous +requests when following a 302 redirection. The non-RFC behavior is ubiquitous in web browsers, so curl does the conversion by default to maintain consistency. However, a server may require a POST to remain a POST after such a redirection. This option is meaningful only when using --location. diff --git a/extern/curl/docs/cmdline-opts/post303.d b/extern/curl/docs/cmdline-opts/post303.d index 44f39e6104..a2fec18c4b 100644 --- a/extern/curl/docs/cmdline-opts/post303.d +++ b/extern/curl/docs/cmdline-opts/post303.d @@ -3,6 +3,8 @@ Help: Do not switch to GET after following a 303 Protocols: HTTP See-also: post302 post301 location Added: 7.26.0 +Category: http post +Example: --post303 --location -d "data" $URL --- Tells curl to violate RFC 7231/6.4.4 and not convert POST requests into GET requests when following 303 redirections. A server may require a POST to diff --git a/extern/curl/docs/cmdline-opts/preproxy.d b/extern/curl/docs/cmdline-opts/preproxy.d index b8eb77fa4f..e5dfb7f949 100644 --- a/extern/curl/docs/cmdline-opts/preproxy.d +++ b/extern/curl/docs/cmdline-opts/preproxy.d @@ -2,6 +2,9 @@ Long: preproxy Arg: [protocol://]host[:port] Help: Use this proxy first Added: 7.52.0 +Category: proxy +Example: --preproxy socks5://proxy.example -x http://http.example $URL +See-also: proxy socks5 --- Use the specified SOCKS proxy before connecting to an HTTP or HTTPS --proxy. In such a case curl first connects to the SOCKS proxy and then connects (through diff --git a/extern/curl/docs/cmdline-opts/progress-bar.d b/extern/curl/docs/cmdline-opts/progress-bar.d index f27de2d930..549acb9b1d 100644 --- a/extern/curl/docs/cmdline-opts/progress-bar.d +++ b/extern/curl/docs/cmdline-opts/progress-bar.d @@ -1,6 +1,10 @@ Short: # Long: progress-bar Help: Display transfer progress as a bar +Category: verbose +Example: -# -O $URL +Added: 5.10 +See-also: styled-output --- Make curl display transfer progress as a simple progress bar instead of the standard, more informational, meter. @@ -10,3 +14,6 @@ shows a percentage if the transfer size is known. For transfers without a known size, there will be space ship (-=o=-) that moves back and forth but only while data is being transferred, with a set of flying hash sign symbols on top. + +This option is global and does not need to be specified for each use of +--next. diff --git a/extern/curl/docs/cmdline-opts/proto-default.d b/extern/curl/docs/cmdline-opts/proto-default.d index ccc3b85f38..86c59f5c60 100644 --- a/extern/curl/docs/cmdline-opts/proto-default.d +++ b/extern/curl/docs/cmdline-opts/proto-default.d @@ -2,17 +2,16 @@ Long: proto-default Help: Use PROTOCOL for any URL missing a scheme Arg: Added: 7.45.0 +Category: connection curl +Example: --proto-default https ftp.example.com +See-also: proto proto-redir --- -Tells curl to use \fIprotocol\fP for any URL missing a scheme name. - -Example: - - curl --proto-default https ftp.mozilla.org +Tells curl to use *protocol* for any URL missing a scheme name. An unknown or unsupported protocol causes error -\fICURLE_UNSUPPORTED_PROTOCOL\fP (1). +*CURLE_UNSUPPORTED_PROTOCOL* (1). This option does not change the default proxy protocol (http). -Without this option curl would make a guess based on the host, see --url for -details. +Without this option set, curl guesses protocol based on the host name, see +--url for details. diff --git a/extern/curl/docs/cmdline-opts/proto-redir.d b/extern/curl/docs/cmdline-opts/proto-redir.d index a1205dd036..d8cd296ffe 100644 --- a/extern/curl/docs/cmdline-opts/proto-redir.d +++ b/extern/curl/docs/cmdline-opts/proto-redir.d @@ -2,6 +2,9 @@ Long: proto-redir Arg: Help: Enable/disable PROTOCOLS on redirect Added: 7.20.2 +Category: connection curl +Example: --proto-redir =http,https $URL +See-also: proto --- Tells curl to limit what protocols it may use on redirect. Protocols denied by --proto are not overridden by this option. See --proto for how protocols are @@ -11,8 +14,6 @@ Example, allow only HTTP and HTTPS on redirect: curl --proto-redir -all,http,https http://example.com -By default curl will allow HTTP, HTTPS, FTP and FTPS on redirect (7.65.2). -Older versions of curl allowed all protocols on redirect except several -disabled for security reasons: Since 7.19.4 FILE and SCP are disabled, and -since 7.40.0 SMB and SMBS are also disabled. Specifying \fIall\fP or \fI+all\fP -enables all protocols on redirect, including those disabled for security. +By default curl will only allow HTTP, HTTPS, FTP and FTPS on redirect (since +7.65.2). Specifying *all* or *+all* enables all protocols on redirects, which +is not good for security. diff --git a/extern/curl/docs/cmdline-opts/proto.d b/extern/curl/docs/cmdline-opts/proto.d index e1ece1788f..6ff52c4174 100644 --- a/extern/curl/docs/cmdline-opts/proto.d +++ b/extern/curl/docs/cmdline-opts/proto.d @@ -3,8 +3,10 @@ Arg: Help: Enable/disable PROTOCOLS See-also: proto-redir proto-default Added: 7.20.2 +Category: connection curl +Example: --proto =http,https,sftp $URL --- -Tells curl to limit what protocols it may use in the transfer. Protocols are +Tells curl to limit what protocols it may use for transfers. Protocols are evaluated left to right, are comma separated, and are each a protocol name or \&'all', optionally prefixed by zero or more modifiers. Available modifiers are: .RS @@ -34,7 +36,7 @@ only enables http and https .B --proto =http,https also only enables http and https .RE - +.IP Unknown protocols produce a warning. This allows scripts to safely rely on being able to disable potentially dangerous protocols, without relying upon support for that protocol being built into curl to avoid an error. diff --git a/extern/curl/docs/cmdline-opts/proxy-anyauth.d b/extern/curl/docs/cmdline-opts/proxy-anyauth.d index b60d0a05e6..80f2b97012 100644 --- a/extern/curl/docs/cmdline-opts/proxy-anyauth.d +++ b/extern/curl/docs/cmdline-opts/proxy-anyauth.d @@ -2,6 +2,8 @@ Long: proxy-anyauth Help: Pick any proxy authentication method Added: 7.13.2 See-also: proxy proxy-basic proxy-digest +Category: proxy auth +Example: --proxy-anyauth --proxy-user user:passwd -x proxy $URL --- Tells curl to pick a suitable authentication method when communicating with the given HTTP proxy. This might cause an extra request/response round-trip. diff --git a/extern/curl/docs/cmdline-opts/proxy-basic.d b/extern/curl/docs/cmdline-opts/proxy-basic.d index 566f890a97..c651badc10 100644 --- a/extern/curl/docs/cmdline-opts/proxy-basic.d +++ b/extern/curl/docs/cmdline-opts/proxy-basic.d @@ -1,6 +1,9 @@ Long: proxy-basic Help: Use Basic authentication on the proxy See-also: proxy proxy-anyauth proxy-digest +Category: proxy auth +Example: --proxy-basic --proxy-user user:passwd -x proxy $URL +Added: 7.12.0 --- Tells curl to use HTTP Basic authentication when communicating with the given proxy. Use --basic for enabling HTTP Basic with a remote host. Basic is the diff --git a/extern/curl/docs/cmdline-opts/proxy-cacert.d b/extern/curl/docs/cmdline-opts/proxy-cacert.d index 2713dd2a4c..5c32944758 100644 --- a/extern/curl/docs/cmdline-opts/proxy-cacert.d +++ b/extern/curl/docs/cmdline-opts/proxy-cacert.d @@ -3,5 +3,7 @@ Help: CA certificate to verify peer against for proxy Arg: Added: 7.52.0 See-also: proxy-capath cacert capath proxy +Category: proxy tls +Example: --proxy-cacert CA-file.txt -x https://proxy $URL --- Same as --cacert but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-capath.d b/extern/curl/docs/cmdline-opts/proxy-capath.d index 177246aabc..0429984f2a 100644 --- a/extern/curl/docs/cmdline-opts/proxy-capath.d +++ b/extern/curl/docs/cmdline-opts/proxy-capath.d @@ -3,5 +3,7 @@ Help: CA directory to verify peer against for proxy Arg: Added: 7.52.0 See-also: proxy-cacert proxy capath +Category: proxy tls +Example: --proxy-capath /local/directory -x https://proxy $URL --- Same as --capath but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-cert-type.d b/extern/curl/docs/cmdline-opts/proxy-cert-type.d index 906d2a1153..9e09fdbbce 100644 --- a/extern/curl/docs/cmdline-opts/proxy-cert-type.d +++ b/extern/curl/docs/cmdline-opts/proxy-cert-type.d @@ -2,5 +2,8 @@ Long: proxy-cert-type Arg: Added: 7.52.0 Help: Client certificate type for HTTPS proxy +Category: proxy tls +Example: --proxy-cert-type PEM --proxy-cert file -x https://proxy $URL +See-also: proxy-cert --- Same as --cert-type but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-cert.d b/extern/curl/docs/cmdline-opts/proxy-cert.d index 43acd39509..5eae2a5495 100644 --- a/extern/curl/docs/cmdline-opts/proxy-cert.d +++ b/extern/curl/docs/cmdline-opts/proxy-cert.d @@ -2,5 +2,8 @@ Long: proxy-cert Arg: Help: Set client certificate for proxy Added: 7.52.0 +Category: proxy tls +Example: --proxy-cert file -x https://proxy $URL +See-also: proxy-cert-type --- Same as --cert but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-ciphers.d b/extern/curl/docs/cmdline-opts/proxy-ciphers.d index dcac812845..aefcc92c0c 100644 --- a/extern/curl/docs/cmdline-opts/proxy-ciphers.d +++ b/extern/curl/docs/cmdline-opts/proxy-ciphers.d @@ -2,5 +2,8 @@ Long: proxy-ciphers Arg: Help: SSL ciphers to use for proxy Added: 7.52.0 +Category: proxy tls +Example: --proxy-ciphers ECDHE-ECDSA-AES256-CCM8 -x https://proxy $URL +See-also: ciphers curves proxy --- Same as --ciphers but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-crlfile.d b/extern/curl/docs/cmdline-opts/proxy-crlfile.d index 1d6247f479..3dd0180754 100644 --- a/extern/curl/docs/cmdline-opts/proxy-crlfile.d +++ b/extern/curl/docs/cmdline-opts/proxy-crlfile.d @@ -2,5 +2,8 @@ Long: proxy-crlfile Arg: Help: Set a CRL list for proxy Added: 7.52.0 +Category: proxy tls +Example: --proxy-crlfile rejects.txt -x https://proxy $URL +See-also: crlfile proxy --- Same as --crlfile but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-digest.d b/extern/curl/docs/cmdline-opts/proxy-digest.d index ccf46636c2..9677e92c57 100644 --- a/extern/curl/docs/cmdline-opts/proxy-digest.d +++ b/extern/curl/docs/cmdline-opts/proxy-digest.d @@ -1,6 +1,9 @@ Long: proxy-digest Help: Use Digest authentication on the proxy See-also: proxy proxy-anyauth proxy-basic +Category: proxy tls +Example: --proxy-digest --proxy-user user:passwd -x proxy $URL +Added: 7.12.0 --- Tells curl to use HTTP Digest authentication when communicating with the given proxy. Use --digest for enabling HTTP Digest with a remote host. diff --git a/extern/curl/docs/cmdline-opts/proxy-header.d b/extern/curl/docs/cmdline-opts/proxy-header.d index c1b0bb7c44..8ea2093877 100644 --- a/extern/curl/docs/cmdline-opts/proxy-header.d +++ b/extern/curl/docs/cmdline-opts/proxy-header.d @@ -3,6 +3,11 @@ Arg:
Help: Pass custom header(s) to proxy Protocols: HTTP Added: 7.37.0 +Category: proxy +Example: --proxy-header "X-First-Name: Joe" -x http://proxy $URL +Example: --proxy-header "User-Agent: surprise" -x http://proxy $URL +Example: --proxy-header "Host:" -x http://proxy $URL +See-also: proxy --- Extra header to include in the request when sending HTTP to a proxy. You may specify any number of extra headers. This is the equivalent option to --header @@ -10,7 +15,7 @@ but is for proxy communication only like in CONNECT requests when you want a separate header sent to the proxy to what is sent to the actual remote host. curl will make sure that each header you add/replace is sent with the proper -end-of-line marker, you should thus \fBnot\fP add that as a part of the header +end-of-line marker, you should thus **not** add that as a part of the header content: do not add newlines or carriage returns, they will only mess things up for you. diff --git a/extern/curl/docs/cmdline-opts/proxy-insecure.d b/extern/curl/docs/cmdline-opts/proxy-insecure.d index 762828f43f..738d42286a 100644 --- a/extern/curl/docs/cmdline-opts/proxy-insecure.d +++ b/extern/curl/docs/cmdline-opts/proxy-insecure.d @@ -1,5 +1,8 @@ Long: proxy-insecure Help: Do HTTPS proxy connections without verifying the proxy Added: 7.52.0 +Category: proxy tls +Example: --proxy-insecure -x https://proxy $URL +See-also: proxy insecure --- Same as --insecure but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-key-type.d b/extern/curl/docs/cmdline-opts/proxy-key-type.d index ce7482ae94..0194ba67c6 100644 --- a/extern/curl/docs/cmdline-opts/proxy-key-type.d +++ b/extern/curl/docs/cmdline-opts/proxy-key-type.d @@ -2,5 +2,8 @@ Long: proxy-key-type Arg: Help: Private key file type for proxy Added: 7.52.0 +Category: proxy tls +Example: --proxy-key-type DER --proxy-key here -x https://proxy $URL +See-also: proxy-key proxy --- Same as --key-type but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-key.d b/extern/curl/docs/cmdline-opts/proxy-key.d index e61eb18a99..bf6868a436 100644 --- a/extern/curl/docs/cmdline-opts/proxy-key.d +++ b/extern/curl/docs/cmdline-opts/proxy-key.d @@ -1,5 +1,9 @@ Long: proxy-key Help: Private key for HTTPS proxy Arg: +Category: proxy tls +Example: --proxy-key here -x https://proxy $URL +Added: 7.52.0 +See-also: proxy-key-type proxy --- Same as --key but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-negotiate.d b/extern/curl/docs/cmdline-opts/proxy-negotiate.d index 775f62a9a3..5085a7cb3a 100644 --- a/extern/curl/docs/cmdline-opts/proxy-negotiate.d +++ b/extern/curl/docs/cmdline-opts/proxy-negotiate.d @@ -2,6 +2,8 @@ Long: proxy-negotiate Help: Use HTTP Negotiate (SPNEGO) authentication on the proxy Added: 7.17.1 See-also: proxy-anyauth proxy-basic +Category: proxy auth +Example: --proxy-negotiate --proxy-user user:passwd -x proxy $URL --- Tells curl to use HTTP Negotiate (SPNEGO) authentication when communicating with the given proxy. Use --negotiate for enabling HTTP Negotiate (SPNEGO) diff --git a/extern/curl/docs/cmdline-opts/proxy-ntlm.d b/extern/curl/docs/cmdline-opts/proxy-ntlm.d index c30db53b9b..03d2d179c2 100644 --- a/extern/curl/docs/cmdline-opts/proxy-ntlm.d +++ b/extern/curl/docs/cmdline-opts/proxy-ntlm.d @@ -1,6 +1,9 @@ Long: proxy-ntlm Help: Use NTLM authentication on the proxy See-also: proxy-negotiate proxy-anyauth +Category: proxy auth +Example: --proxy-ntlm --proxy-user user:passwd -x http://proxy $URL +Added: 7.10.7 --- Tells curl to use HTTP NTLM authentication when communicating with the given proxy. Use --ntlm for enabling NTLM with a remote host. diff --git a/extern/curl/docs/cmdline-opts/proxy-pass.d b/extern/curl/docs/cmdline-opts/proxy-pass.d index 3371714ba0..a513991d07 100644 --- a/extern/curl/docs/cmdline-opts/proxy-pass.d +++ b/extern/curl/docs/cmdline-opts/proxy-pass.d @@ -2,5 +2,8 @@ Long: proxy-pass Arg: Help: Pass phrase for the private key for HTTPS proxy Added: 7.52.0 +Category: proxy tls auth +Example: --proxy-pass secret --proxy-key here -x https://proxy $URL +See-also: proxy proxy-key --- Same as --pass but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-pinnedpubkey.d b/extern/curl/docs/cmdline-opts/proxy-pinnedpubkey.d index abd6dc4aaf..4e168ef6c1 100644 --- a/extern/curl/docs/cmdline-opts/proxy-pinnedpubkey.d +++ b/extern/curl/docs/cmdline-opts/proxy-pinnedpubkey.d @@ -2,11 +2,16 @@ Long: proxy-pinnedpubkey Arg: Help: FILE/HASHES public key to verify proxy with Protocols: TLS +Category: proxy tls +Example: --proxy-pinnedpubkey keyfile $URL +Example: --proxy-pinnedpubkey 'sha256//ce118b51897f4452dc' $URL +Added: 7.59.0 +See-also: pinnedpubkey proxy --- Tells curl to use the specified public key file (or hashes) to verify the proxy. This can be a path to a file which contains a single public key in PEM or DER format, or any number of base64 encoded sha256 hashes preceded by -\'sha256//\' and separated by \';\' +'sha256//' and separated by ';'. When negotiating a TLS or SSL connection, the server sends a certificate indicating its identity. A public key is extracted from this certificate and diff --git a/extern/curl/docs/cmdline-opts/proxy-service-name.d b/extern/curl/docs/cmdline-opts/proxy-service-name.d index 9a73f2be62..230b802d78 100644 --- a/extern/curl/docs/cmdline-opts/proxy-service-name.d +++ b/extern/curl/docs/cmdline-opts/proxy-service-name.d @@ -2,5 +2,8 @@ Long: proxy-service-name Arg: Help: SPNEGO proxy service name Added: 7.43.0 +Category: proxy tls +Example: --proxy-service-name "shrubbery" -x proxy $URL +See-also: service-name proxy --- This option allows you to change the service name for proxy negotiation. diff --git a/extern/curl/docs/cmdline-opts/proxy-ssl-allow-beast.d b/extern/curl/docs/cmdline-opts/proxy-ssl-allow-beast.d index de96b8436d..d712429e3e 100644 --- a/extern/curl/docs/cmdline-opts/proxy-ssl-allow-beast.d +++ b/extern/curl/docs/cmdline-opts/proxy-ssl-allow-beast.d @@ -1,5 +1,8 @@ Long: proxy-ssl-allow-beast Help: Allow security flaw for interop for HTTPS proxy Added: 7.52.0 +Category: proxy tls +Example: --proxy-ssl-allow-beast -x https://proxy $URL +See-also: ssl-allow-beast proxy --- Same as --ssl-allow-beast but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-ssl-auto-client-cert.d b/extern/curl/docs/cmdline-opts/proxy-ssl-auto-client-cert.d new file mode 100644 index 0000000000..77eb535202 --- /dev/null +++ b/extern/curl/docs/cmdline-opts/proxy-ssl-auto-client-cert.d @@ -0,0 +1,8 @@ +Long: proxy-ssl-auto-client-cert +Help: Use auto client certificate for proxy (Schannel) +Added: 7.77.0 +Category: proxy tls +Example: --proxy-ssl-auto-client-cert -x https://proxy $URL +See-also: ssl-auto-client-cert proxy +--- +Same as --ssl-auto-client-cert but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-tls13-ciphers.d b/extern/curl/docs/cmdline-opts/proxy-tls13-ciphers.d index 08961b72e4..5ec835c7fe 100644 --- a/extern/curl/docs/cmdline-opts/proxy-tls13-ciphers.d +++ b/extern/curl/docs/cmdline-opts/proxy-tls13-ciphers.d @@ -2,12 +2,16 @@ Long: proxy-tls13-ciphers Arg: help: TLS 1.3 proxy cipher suites Protocols: TLS +Category: proxy tls +Example: --proxy-tls13-ciphers TLS_AES_128_GCM_SHA256 -x proxy $URL +Added: 7.61.0 +See-also: tls13-ciphers curves --- Specifies which cipher suites to use in the connection to your HTTPS proxy when it negotiates TLS 1.3. The list of ciphers suites must specify valid ciphers. Read up on TLS 1.3 cipher suite details on this URL: - https://curl.haxx.se/docs/ssl-ciphers.html + https://curl.se/docs/ssl-ciphers.html This option is currently used only when curl is built to use OpenSSL 1.1.1 or later. If you are using a different SSL backend you can try setting TLS 1.3 diff --git a/extern/curl/docs/cmdline-opts/proxy-tlsauthtype.d b/extern/curl/docs/cmdline-opts/proxy-tlsauthtype.d index 7d0ce8e1a7..4d58af5a2b 100644 --- a/extern/curl/docs/cmdline-opts/proxy-tlsauthtype.d +++ b/extern/curl/docs/cmdline-opts/proxy-tlsauthtype.d @@ -2,5 +2,8 @@ Long: proxy-tlsauthtype Arg: Help: TLS authentication type for HTTPS proxy Added: 7.52.0 +Category: proxy tls auth +Example: --proxy-tlsauthtype SRP -x https://proxy $URL +See-also: proxy proxy-tlsuser --- Same as --tlsauthtype but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-tlspassword.d b/extern/curl/docs/cmdline-opts/proxy-tlspassword.d index cf003844e0..6b41ed3c99 100644 --- a/extern/curl/docs/cmdline-opts/proxy-tlspassword.d +++ b/extern/curl/docs/cmdline-opts/proxy-tlspassword.d @@ -2,5 +2,8 @@ Long: proxy-tlspassword Arg: Help: TLS password for HTTPS proxy Added: 7.52.0 +Category: proxy tls auth +Example: --proxy-tlspassword passwd -x https://proxy $URL +See-also: proxy proxy-tlsuser --- Same as --tlspassword but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-tlsuser.d b/extern/curl/docs/cmdline-opts/proxy-tlsuser.d index 758a7c953a..8291ab26ab 100644 --- a/extern/curl/docs/cmdline-opts/proxy-tlsuser.d +++ b/extern/curl/docs/cmdline-opts/proxy-tlsuser.d @@ -2,5 +2,8 @@ Long: proxy-tlsuser Arg: Help: TLS username for HTTPS proxy Added: 7.52.0 +Category: proxy tls auth +Example: --proxy-tlsuser smith -x https://proxy $URL +See-also: proxy proxy-tlspassword --- Same as --tlsuser but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-tlsv1.d b/extern/curl/docs/cmdline-opts/proxy-tlsv1.d index d024eeac36..7175e61741 100644 --- a/extern/curl/docs/cmdline-opts/proxy-tlsv1.d +++ b/extern/curl/docs/cmdline-opts/proxy-tlsv1.d @@ -1,5 +1,8 @@ Long: proxy-tlsv1 Help: Use TLSv1 for HTTPS proxy Added: 7.52.0 +Category: proxy tls auth +Example: --proxy-tlsv1 -x https://proxy $URL +See-also: proxy --- Same as --tlsv1 but used in HTTPS proxy context. diff --git a/extern/curl/docs/cmdline-opts/proxy-user.d b/extern/curl/docs/cmdline-opts/proxy-user.d index 152466daaa..81ed55be55 100644 --- a/extern/curl/docs/cmdline-opts/proxy-user.d +++ b/extern/curl/docs/cmdline-opts/proxy-user.d @@ -2,6 +2,10 @@ Long: proxy-user Short: U Arg: Help: Proxy user and password +Category: proxy auth +Example: --proxy-user name:pwd -x proxy $URL +Added: 4.0 +See-also: proxy-pass --- Specify the user name and password to use for proxy authentication. @@ -12,7 +16,7 @@ from your environment by specifying a single colon with this option: "-U :". On systems where it works, curl will hide the given option argument from process listings. This is not enough to protect credentials from possibly getting seen by other users on the same system as they will still be visible -for a brief moment before cleared. Such sensitive data should be retrieved -from a file instead or similar and never used in clear text in a command line. +for a moment before cleared. Such sensitive data should be retrieved from a +file instead or similar and never used in clear text in a command line. If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/proxy.d b/extern/curl/docs/cmdline-opts/proxy.d index 6506692be8..60674b5f89 100644 --- a/extern/curl/docs/cmdline-opts/proxy.d +++ b/extern/curl/docs/cmdline-opts/proxy.d @@ -2,13 +2,17 @@ Long: proxy Short: x Arg: [protocol://]host[:port] Help: Use this proxy +Category: proxy +Example: --proxy http://proxy.example $URL +Added: 4.0 +See-also: socks5 proxy-basic --- Use the specified proxy. The proxy string can be specified with a protocol:// prefix. No protocol specified or http:// will be treated as HTTP proxy. Use socks4://, socks4a://, socks5:// or socks5h:// to request a specific SOCKS version to be used. -(The protocol support was added in curl 7.21.7) +(Added in 7.21.7) HTTPS proxy support via https:// protocol prefix was added in 7.52.0 for OpenSSL, GnuTLS and NSS. @@ -32,7 +36,7 @@ User and password that might be provided in the proxy string are URL decoded by curl. This allows you to pass in special characters such as @ by using %40 or pass in a colon with %3a. -The proxy host can be specified the exact same way as the proxy environment +The proxy host can be specified the same way as the proxy environment variables, including the protocol prefix (http://) and the embedded user + password. diff --git a/extern/curl/docs/cmdline-opts/proxy1.0.d b/extern/curl/docs/cmdline-opts/proxy1.0.d index 4a931bd15b..65faf4b35f 100644 --- a/extern/curl/docs/cmdline-opts/proxy1.0.d +++ b/extern/curl/docs/cmdline-opts/proxy1.0.d @@ -1,6 +1,10 @@ Long: proxy1.0 Arg: Help: Use HTTP/1.0 proxy on given port +Category: proxy +Example: --proxy1.0 -x http://proxy $URL +Added: 7.19.4 +See-also: proxy socks5 preproxy --- Use the specified HTTP 1.0 proxy. If the port number is not specified, it is assumed at port 1080. diff --git a/extern/curl/docs/cmdline-opts/proxytunnel.d b/extern/curl/docs/cmdline-opts/proxytunnel.d index 1f587f1209..a62cbb6947 100644 --- a/extern/curl/docs/cmdline-opts/proxytunnel.d +++ b/extern/curl/docs/cmdline-opts/proxytunnel.d @@ -2,6 +2,9 @@ Long: proxytunnel Short: p Help: Operate through an HTTP proxy tunnel (using CONNECT) See-also: proxy +Category: proxy +Example: --proxytunnel -x http://proxy $URL +Added: 7.3 --- When an HTTP proxy is used --proxy, this option will make curl tunnel through the proxy. The tunnel approach is made with the HTTP proxy CONNECT request and diff --git a/extern/curl/docs/cmdline-opts/pubkey.d b/extern/curl/docs/cmdline-opts/pubkey.d index b2e11c024b..277904912d 100644 --- a/extern/curl/docs/cmdline-opts/pubkey.d +++ b/extern/curl/docs/cmdline-opts/pubkey.d @@ -2,6 +2,10 @@ Long: pubkey Arg: Protocols: SFTP SCP Help: SSH Public key file name +Category: sftp scp auth +Example: --pubkey file.pub sftp://example.com/ +Added: 7.16.2 +See-also: pass --- Public key file name. Allows you to provide your public key in this separate file. diff --git a/extern/curl/docs/cmdline-opts/quote.d b/extern/curl/docs/cmdline-opts/quote.d index 59a98eafbc..3e74604dea 100644 --- a/extern/curl/docs/cmdline-opts/quote.d +++ b/extern/curl/docs/cmdline-opts/quote.d @@ -1,31 +1,43 @@ Long: quote +Arg: Short: Q Help: Send command(s) to server before transfer Protocols: FTP SFTP +Category: ftp sftp +Example: --quote "DELE file" ftp://example.com/foo +Added: 5.3 +See-also: request --- - Send an arbitrary command to the remote FTP or SFTP server. Quote commands are sent BEFORE the transfer takes place (just after the initial PWD command in an FTP transfer, to be exact). To make commands take place after a successful -transfer, prefix them with a dash '-'. To make commands be sent after curl -has changed the working directory, just before the transfer command(s), prefix -the command with a '+' (this is only supported for FTP). You may specify any -number of commands. +transfer, prefix them with a dash '-'. + +(FTP only) To make commands be sent after curl has changed the working +directory, just before the file transfer command(s), prefix the command with a +'+'. This is not performed when a directory listing is performed. + +You may specify any number of commands. -If the server returns failure for one of the commands, the entire operation -will be aborted. You must send syntactically correct FTP commands as RFC 959 -defines to FTP servers, or one of the commands listed below to SFTP servers. +By default curl will stop at first failure. To make curl continue even if the +command fails, prefix the command with an asterisk (*). Otherwise, if the +server returns failure for one of the commands, the entire operation will be +aborted. -Prefix the command with an asterisk (*) to make curl continue even if the -command fails as by default curl will stop at first failure. +You must send syntactically correct FTP commands as RFC 959 defines to FTP +servers, or one of the commands listed below to SFTP servers. This option can be used multiple times. SFTP is a binary protocol. Unlike for FTP, curl interprets SFTP quote commands -itself before sending them to the server. File names may be quoted -shell-style to embed spaces or special characters. Following is the list of +itself before sending them to the server. File names may be quoted +shell-style to embed spaces or special characters. Following is the list of all supported SFTP quote commands: .RS +.IP "atime date file" +The atime command sets the last access time of the file named by the file +operand. The can be all sorts of date strings, see the +*curl_getdate(3)* man page for date expression details. (Added in 7.73.0) .IP "chgrp group file" The chgrp command sets the group ID of the file named by the file operand to the group ID specified by the group operand. The group operand is a decimal @@ -42,6 +54,10 @@ The ln and symlink commands create a symbolic link at the target_file location pointing to the source_file location. .IP "mkdir directory_name" The mkdir command creates the directory named by the directory_name operand. +.IP "mtime date file" +The mtime command sets the last modification time of the file named by the +file operand. The can be all sorts of date strings, see the +*curl_getdate(3)* man page for date expression details. (Added in 7.73.0) .IP "pwd" The pwd command returns the absolute pathname of the current working directory. .IP "rename source target" diff --git a/extern/curl/docs/cmdline-opts/random-file.d b/extern/curl/docs/cmdline-opts/random-file.d index 51626f88dc..fe56f574fa 100644 --- a/extern/curl/docs/cmdline-opts/random-file.d +++ b/extern/curl/docs/cmdline-opts/random-file.d @@ -1,7 +1,11 @@ Long: random-file Arg: Help: File for reading random data from +Category: misc +Example: --random-file rubbish $URL +Added: 7.7 +See-also: egd-file --- Specify the path name to file containing what will be considered as random -data. The data may be used to seed the random engine for SSL connections. See +data. The data may be used to seed the random engine for SSL connections. See also the --egd-file option. diff --git a/extern/curl/docs/cmdline-opts/range.d b/extern/curl/docs/cmdline-opts/range.d index b888dd1814..7ebf843aa4 100644 --- a/extern/curl/docs/cmdline-opts/range.d +++ b/extern/curl/docs/cmdline-opts/range.d @@ -3,6 +3,10 @@ Short: r Help: Retrieve only the bytes within RANGE Arg: Protocols: HTTP FTP SFTP FILE +Category: http ftp sftp file +Example: --range 22-44 $URL +Added: 4.0 +See-also: continue-at append --- Retrieve a byte range (i.e. a partial document) from an HTTP/1.1, FTP or SFTP server or a local FILE. Ranges can be specified in a number of ways. @@ -28,7 +32,8 @@ specifies two separate 100-byte ranges(*) (HTTP) .RE .IP (*) = NOTE that this will cause the server to reply with a multipart -response! +response, which will be returned as-is by curl! Parsing or otherwise +transforming this response is the responsibility of the caller. Only digit characters (0-9) are valid in the 'start' and 'stop' fields of the \&'start-stop' range syntax. If a non-digit character is given in the range, @@ -36,8 +41,8 @@ the server's response will be unspecified, depending on the server's configuration. You should also be aware that many HTTP/1.1 servers do not have this feature -enabled, so that when you attempt to get a range, you'll instead get the whole -document. +enabled, so that when you attempt to get a range, you will instead get the +whole document. FTP and SFTP range downloads only support the simple 'start-stop' syntax (optionally with one of the numbers omitted). FTP use depends on the extended diff --git a/extern/curl/docs/cmdline-opts/raw.d b/extern/curl/docs/cmdline-opts/raw.d index c3328e69a1..dcf77fc46f 100644 --- a/extern/curl/docs/cmdline-opts/raw.d +++ b/extern/curl/docs/cmdline-opts/raw.d @@ -2,6 +2,9 @@ Long: raw Help: Do HTTP "raw"; no transfer decoding Added: 7.16.2 Protocols: HTTP +Category: http +Example: --raw $URL +See-also: tr-encoding --- When used, it disables all internal HTTP decoding of content or transfer encodings and instead makes them passed on unaltered, raw. diff --git a/extern/curl/docs/cmdline-opts/referer.d b/extern/curl/docs/cmdline-opts/referer.d index cd84e9d5a0..10aa8297e0 100644 --- a/extern/curl/docs/cmdline-opts/referer.d +++ b/extern/curl/docs/cmdline-opts/referer.d @@ -4,11 +4,16 @@ Arg: Protocols: HTTP Help: Referrer URL See-also: user-agent header +Category: http +Example: --referer "https://fake.example" $URL +Example: --referer "https://fake.example;auto" -L $URL +Example: --referer ";auto" -L $URL +Added: 4.0 --- Sends the "Referrer Page" information to the HTTP server. This can also be set -with the --header flag of course. When used with --location you can append +with the --header flag of course. When used with --location you can append ";auto" to the --referer URL to make curl automatically set the previous URL when it follows a Location: header. The \&";auto" string can be used alone, -even if you don't set an initial --referer. +even if you do not set an initial --referer. If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/remote-header-name.d b/extern/curl/docs/cmdline-opts/remote-header-name.d index 771b6d4699..b9550deed2 100644 --- a/extern/curl/docs/cmdline-opts/remote-header-name.d +++ b/extern/curl/docs/cmdline-opts/remote-header-name.d @@ -2,18 +2,27 @@ Long: remote-header-name Short: J Protocols: HTTP Help: Use the header-provided filename +Category: output +Example: -OJ https://example.com/file +Added: 7.20.0 +See-also: remote-name --- This option tells the --remote-name option to use the server-specified -Content-Disposition filename instead of extracting a filename from the URL. +Content-Disposition filename instead of extracting a filename from the URL. If +the server-provided file name contains a path, that will be stripped off +before the file name is used. + +The file is saved in the current directory, or in the directory specified with +--output-dir. If the server specifies a file name and a file with that name already exists -in the current working directory it will not be overwritten and an error will -occur. If the server doesn't specify a file name then this option has no +in the destination directory, it will not be overwritten and an error will +occur. If the server does not specify a file name then this option has no effect. There's no attempt to decode %-sequences (yet) in the provided file name, so this option may provide you with rather unexpected file names. -\fBWARNING\fP: Exercise judicious use of this option, especially on Windows. A -rogue server could send you the name of a DLL or other file that could possibly -be loaded automatically by Windows or some third party software. +**WARNING**: Exercise judicious use of this option, especially on Windows. A +rogue server could send you the name of a DLL or other file that could be +loaded automatically by Windows or some third party software. diff --git a/extern/curl/docs/cmdline-opts/remote-name-all.d b/extern/curl/docs/cmdline-opts/remote-name-all.d index f7a1996793..80e8a0a2e2 100644 --- a/extern/curl/docs/cmdline-opts/remote-name-all.d +++ b/extern/curl/docs/cmdline-opts/remote-name-all.d @@ -1,6 +1,9 @@ Long: remote-name-all Help: Use the remote file name for all URLs Added: 7.19.0 +Category: output +Example: --remote-name-all ftp://example.com/file1 ftp://example.com/file2 +See-also: remote-name --- This option changes the default action for all given URLs to be dealt with as if --remote-name were used for each one. So if you want to disable that for a diff --git a/extern/curl/docs/cmdline-opts/remote-name.d b/extern/curl/docs/cmdline-opts/remote-name.d index 9fed64bf4f..c149c185c6 100644 --- a/extern/curl/docs/cmdline-opts/remote-name.d +++ b/extern/curl/docs/cmdline-opts/remote-name.d @@ -1,6 +1,10 @@ Long: remote-name Short: O Help: Write output to a file named as the remote file +Category: important output +Example: -O https://example.com/filename +Added: 4.0 +See-also: remote-name-all --- Write output to a local file named like the remote file we get. (Only the file part of the remote file is used, the path is cut off.) diff --git a/extern/curl/docs/cmdline-opts/remote-time.d b/extern/curl/docs/cmdline-opts/remote-time.d index 7f6809dc35..5728737237 100644 --- a/extern/curl/docs/cmdline-opts/remote-time.d +++ b/extern/curl/docs/cmdline-opts/remote-time.d @@ -1,6 +1,10 @@ Long: remote-time Short: R Help: Set the remote file's time on the local output +Category: output +Example: --remote-time -o foo $URL +Added: 7.9 +See-also: remote-name time-cond --- When used, this will make curl attempt to figure out the timestamp of the remote file, and if that is available make the local file get that same diff --git a/extern/curl/docs/cmdline-opts/remove-on-error.d b/extern/curl/docs/cmdline-opts/remove-on-error.d new file mode 100644 index 0000000000..01b57f12e7 --- /dev/null +++ b/extern/curl/docs/cmdline-opts/remove-on-error.d @@ -0,0 +1,12 @@ +Long: remove-on-error +Help: Remove output file on errors +See-also: fail +Category: curl +Example: --remove-on-error -o output $URL +Added: 7.83.0 +--- +When curl returns an error when told to save output in a local file, this +option removes that saved file before exiting. This prevents curl from +leaving a partial file in the case of an error during transfer. + +If the output is not a file, this option has no effect. diff --git a/extern/curl/docs/cmdline-opts/request-target.d b/extern/curl/docs/cmdline-opts/request-target.d index b46b4af02e..d901fd8871 100644 --- a/extern/curl/docs/cmdline-opts/request-target.d +++ b/extern/curl/docs/cmdline-opts/request-target.d @@ -1,9 +1,13 @@ Long: request-target +Arg: Help: Specify the target for this request Protocols: HTTP Added: 7.55.0 +Category: http +Example: --request-target "*" -X OPTIONS $URL +See-also: request --- Tells curl to use an alternative "target" (path) instead of using the path as provided in the URL. Particularly useful when wanting to issue HTTP requests -without leading slash or other data that doesn't follow the regular URL +without leading slash or other data that does not follow the regular URL pattern, like "OPTIONS *". diff --git a/extern/curl/docs/cmdline-opts/request.d b/extern/curl/docs/cmdline-opts/request.d index 3919d426a5..9a97149fb4 100644 --- a/extern/curl/docs/cmdline-opts/request.d +++ b/extern/curl/docs/cmdline-opts/request.d @@ -1,16 +1,21 @@ Long: request Short: X -Arg: -Help: Specify request command to use +Arg: +Help: Specify request method to use +Category: connection +Example: -X "DELETE" $URL +Example: -X NLST ftp://example.com/ +Added: 6.0 +See-also: request-target --- (HTTP) Specifies a custom request method to use when communicating with the -HTTP server. The specified request method will be used instead of the method +HTTP server. The specified request method will be used instead of the method otherwise used (which defaults to GET). Read the HTTP 1.1 specification for details and explanations. Common additional HTTP requests include PUT and DELETE, but related technologies like WebDAV offers PROPFIND, COPY, MOVE and more. -Normally you don't need this option. All sorts of GET, HEAD, POST and PUT +Normally you do not need this option. All sorts of GET, HEAD, POST and PUT requests are rather invoked by using dedicated command line options. This option only changes the actual word used in the HTTP request, it does not @@ -19,7 +24,7 @@ request, using -X HEAD will not suffice. You need to use the --head option. The method string you set with --request will be used for all requests, which if you for example use --location may cause unintended side-effects when curl -doesn't change request method according to the HTTP 30x response codes - and +does not change request method according to the HTTP 30x response codes - and similar. (FTP) @@ -27,8 +32,8 @@ Specifies a custom FTP command to use instead of LIST when doing file lists with FTP. (POP3) -Specifies a custom POP3 command to use instead of LIST or RETR. (Added in -7.26.0) +Specifies a custom POP3 command to use instead of LIST or RETR. +(Added in 7.26.0) (IMAP) Specifies a custom IMAP command to use instead of LIST. (Added in 7.30.0) diff --git a/extern/curl/docs/cmdline-opts/resolve.d b/extern/curl/docs/cmdline-opts/resolve.d index 9c37525bd9..cbe2887389 100644 --- a/extern/curl/docs/cmdline-opts/resolve.d +++ b/extern/curl/docs/cmdline-opts/resolve.d @@ -1,7 +1,10 @@ Long: resolve -Arg: +Arg: <[+]host:port:addr[,addr]...> Help: Resolve the host+port to this address Added: 7.21.3 +Category: connection +Example: --resolve example.com:443:127.0.0.1 $URL +See-also: connect-to alt-svc --- Provide a custom address for a specific host and port pair. Using this, you can make the curl requests(s) use a specified address and prevent the @@ -18,10 +21,18 @@ with a specific host and port will be used first. The provided address set by this option will be used even if --ipv4 or --ipv6 is set to make curl use another IP version. +By prefixing the host with a '+' you can make the entry time out after curl's +default timeout (1 minute). Note that this will only make sense for long +running parallel transfers with a lot of files. In such cases, if this option +is used curl will try to resolve the host as it normally would once the +timeout has expired. + Support for providing the IP address within [brackets] was added in 7.57.0. Support for providing multiple IP addresses per entry was added in 7.59.0. Support for resolving with wildcard was added in 7.64.0. +Support for the '+' prefix was was added in 7.75.0. + This option can be used many times to add many host names to resolve. diff --git a/extern/curl/docs/cmdline-opts/retry-all-errors.d b/extern/curl/docs/cmdline-opts/retry-all-errors.d new file mode 100644 index 0000000000..37fdfc7319 --- /dev/null +++ b/extern/curl/docs/cmdline-opts/retry-all-errors.d @@ -0,0 +1,31 @@ +Long: retry-all-errors +Help: Retry all errors (use with --retry) +Added: 7.71.0 +Category: curl +Example: --retry 5 --retry-all-errors $URL +See-also: retry +--- +Retry on any error. This option is used together with --retry. + +This option is the "sledgehammer" of retrying. Do not use this option by +default (eg in curlrc), there may be unintended consequences such as sending or +receiving duplicate data. Do not use with redirected input or output. You'd be +much better off handling your unique problems in shell script. Please read the +example below. + +**WARNING**: For server compatibility curl attempts to retry failed flaky +transfers as close as possible to how they were started, but this is not +possible with redirected input or output. For example, before retrying it +removes output data from a failed partial transfer that was written to an +output file. However this is not true of data redirected to a | pipe or > +file, which are not reset. We strongly suggest you do not parse or record +output via redirect in combination with this option, since you may receive +duplicate data. + +By default curl will not error on an HTTP response code that indicates an HTTP +error, if the transfer was successful. For example, if a server replies 404 +Not Found and the reply is fully received then that is not an error. When +--retry is used then curl will retry on some HTTP response codes that indicate +transient HTTP errors, but that does not include most 4xx response codes such +as 404. If you want to retry on all response codes that indicate HTTP errors +(4xx and 5xx) then combine with --fail. diff --git a/extern/curl/docs/cmdline-opts/retry-connrefused.d b/extern/curl/docs/cmdline-opts/retry-connrefused.d index 6a78e1fdaa..13574e80c9 100644 --- a/extern/curl/docs/cmdline-opts/retry-connrefused.d +++ b/extern/curl/docs/cmdline-opts/retry-connrefused.d @@ -1,6 +1,9 @@ Long: retry-connrefused Help: Retry on connection refused (use with --retry) Added: 7.52.0 +Category: curl +Example: --retry-connrefused --retry $URL +See-also: retry retry-all-errors --- In addition to the other conditions, consider ECONNREFUSED as a transient error too for --retry. This option is used together with --retry. diff --git a/extern/curl/docs/cmdline-opts/retry-delay.d b/extern/curl/docs/cmdline-opts/retry-delay.d index 1691356d4c..c4970bc8c5 100644 --- a/extern/curl/docs/cmdline-opts/retry-delay.d +++ b/extern/curl/docs/cmdline-opts/retry-delay.d @@ -2,6 +2,9 @@ Long: retry-delay Arg: Help: Wait time between retries Added: 7.12.3 +Category: curl +Example: --retry-delay 5 --retry $URL +See-also: retry --- Make curl sleep this amount of time before each retry when a transfer has failed with a transient error (it changes the default backoff time algorithm diff --git a/extern/curl/docs/cmdline-opts/retry-max-time.d b/extern/curl/docs/cmdline-opts/retry-max-time.d index 0920c92446..88ce20f7dd 100644 --- a/extern/curl/docs/cmdline-opts/retry-max-time.d +++ b/extern/curl/docs/cmdline-opts/retry-max-time.d @@ -2,12 +2,15 @@ Long: retry-max-time Arg: Help: Retry only within this period Added: 7.12.3 +Category: curl +Example: --retry-max-time 30 --retry 10 $URL +See-also: retry --- The retry timer is reset before the first transfer attempt. Retries will be -done as usual (see --retry) as long as the timer hasn't reached this given -limit. Notice that if the timer hasn't reached the limit, the request will be +done as usual (see --retry) as long as the timer has not reached this given +limit. Notice that if the timer has not reached the limit, the request will be made and while performing, it may take longer than this given time period. To -limit a single request\'s maximum time, use --max-time. Set this option to +limit a single request's maximum time, use --max-time. Set this option to zero to not timeout retries. If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/retry.d b/extern/curl/docs/cmdline-opts/retry.d index 3db89b71c0..428a092e6a 100644 --- a/extern/curl/docs/cmdline-opts/retry.d +++ b/extern/curl/docs/cmdline-opts/retry.d @@ -2,15 +2,19 @@ Long: retry Arg: Added: 7.12.3 Help: Retry request if transient problems occur +Category: curl +Example: --retry 7 $URL +See-also: retry-max-time --- If a transient error is returned when curl tries to perform a transfer, it will retry this number of times before giving up. Setting the number to 0 makes curl do no retries (which is the default). Transient error means either: -a timeout, an FTP 4xx response code or an HTTP 408 or 5xx response code. +a timeout, an FTP 4xx response code or an HTTP 408, 429, 500, 502, 503 or 504 +response code. When curl is about to retry a transfer, it will first wait one second and then for all forthcoming retries it will double the waiting time until it reaches -10 minutes which then will be the delay between the rest of the retries. By +10 minutes which then will be the delay between the rest of the retries. By using --retry-delay you disable this exponential backoff algorithm. See also --retry-max-time to limit the total time allowed for retries. diff --git a/extern/curl/docs/cmdline-opts/sasl-authzid.d b/extern/curl/docs/cmdline-opts/sasl-authzid.d index b34db97fc0..4e2a419a97 100644 --- a/extern/curl/docs/cmdline-opts/sasl-authzid.d +++ b/extern/curl/docs/cmdline-opts/sasl-authzid.d @@ -1,11 +1,15 @@ Long: sasl-authzid -Help: Use this identity to act as during SASL PLAIN authentication +Arg: +Help: Identity for SASL PLAIN authentication Added: 7.66.0 +Category: auth +Example: --sasl-authzid zid imap://example.com/ +See-also: login-options --- -Use this authorisation identity (authzid), during SASL PLAIN authentication, +Use this authorization identity (authzid), during SASL PLAIN authentication, in addition to the authentication identity (authcid) as specified by --user. -If the option isn't specified, the server will derive the authzid from the +If the option is not specified, the server will derive the authzid from the authcid, but if specified, and depending on the server implementation, it may be used to access another user's inbox, that the user has been granted access to, or a shared mailbox for example. diff --git a/extern/curl/docs/cmdline-opts/sasl-ir.d b/extern/curl/docs/cmdline-opts/sasl-ir.d index c0dab94635..f1289fd764 100644 --- a/extern/curl/docs/cmdline-opts/sasl-ir.d +++ b/extern/curl/docs/cmdline-opts/sasl-ir.d @@ -1,5 +1,8 @@ Long: sasl-ir Help: Enable initial response in SASL authentication Added: 7.31.0 +Category: auth +Example: --sasl-ir imap://example.com/ +See-also: sasl-authzid --- Enable initial response in SASL authentication. diff --git a/extern/curl/docs/cmdline-opts/service-name.d b/extern/curl/docs/cmdline-opts/service-name.d index 4dfeb27d65..fd9cb436bb 100644 --- a/extern/curl/docs/cmdline-opts/service-name.d +++ b/extern/curl/docs/cmdline-opts/service-name.d @@ -2,6 +2,9 @@ Long: service-name Help: SPNEGO service name Arg: Added: 7.43.0 +Category: misc +Example: --service-name sockd/server $URL +See-also: negotiate proxy-service-name --- This option allows you to change the service name for SPNEGO. diff --git a/extern/curl/docs/cmdline-opts/show-error.d b/extern/curl/docs/cmdline-opts/show-error.d index b9667a4ca5..c1af391d08 100644 --- a/extern/curl/docs/cmdline-opts/show-error.d +++ b/extern/curl/docs/cmdline-opts/show-error.d @@ -1,5 +1,12 @@ Long: show-error Short: S Help: Show error even when -s is used +See-also: no-progress-meter +Category: curl +Example: --show-error --silent $URL +Added: 5.9 --- When used with --silent, it makes curl show an error message if it fails. + +This option is global and does not need to be specified for each use of +--next. diff --git a/extern/curl/docs/cmdline-opts/silent.d b/extern/curl/docs/cmdline-opts/silent.d index b0b4425b3d..3834ee62ca 100644 --- a/extern/curl/docs/cmdline-opts/silent.d +++ b/extern/curl/docs/cmdline-opts/silent.d @@ -1,9 +1,12 @@ Long: silent Short: s Help: Silent mode -See-also: verbose stderr +See-also: verbose stderr no-progress-meter +Category: important verbose +Example: -s $URL +Added: 4.0 --- -Silent or quiet mode. Don't show progress meter or error messages. Makes Curl +Silent or quiet mode. Do not show progress meter or error messages. Makes Curl mute. It will still output the data you ask for, potentially even to the terminal/stdout unless you redirect it. diff --git a/extern/curl/docs/cmdline-opts/socks4.d b/extern/curl/docs/cmdline-opts/socks4.d index 11f6ae033e..a1fb1b3445 100644 --- a/extern/curl/docs/cmdline-opts/socks4.d +++ b/extern/curl/docs/cmdline-opts/socks4.d @@ -2,15 +2,19 @@ Long: socks4 Arg: Help: SOCKS4 proxy on given host + port Added: 7.15.2 +Category: proxy +Example: --socks4 hostname:4096 $URL +See-also: socks4a socks5 socks5-hostname --- Use the specified SOCKS4 proxy. If the port number is not specified, it is -assumed at port 1080. +assumed at port 1080. Using this socket type make curl resolve the host name +and passing the address on to the proxy. This option overrides any previous use of --proxy, as they are mutually exclusive. -Since 7.21.7, this option is superfluous since you can specify a socks4 proxy -with --proxy using a socks4:// protocol prefix. +This option is superfluous since you can specify a socks4 proxy with --proxy +using a socks4:// protocol prefix. (Added in 7.21.7) Since 7.52.0, --preproxy can be used to specify a SOCKS proxy at the same time --proxy is used with an HTTP/HTTPS proxy. In such a case curl first connects to diff --git a/extern/curl/docs/cmdline-opts/socks4a.d b/extern/curl/docs/cmdline-opts/socks4a.d index ae254ae0e8..e39b968aab 100644 --- a/extern/curl/docs/cmdline-opts/socks4a.d +++ b/extern/curl/docs/cmdline-opts/socks4a.d @@ -2,15 +2,18 @@ Long: socks4a Arg: Help: SOCKS4a proxy on given host + port Added: 7.18.0 +Category: proxy +Example: --socks4a hostname:4096 $URL +See-also: socks4 socks5 socks5-hostname --- Use the specified SOCKS4a proxy. If the port number is not specified, it is -assumed at port 1080. +assumed at port 1080. This asks the proxy to resolve the host name. This option overrides any previous use of --proxy, as they are mutually exclusive. -Since 7.21.7, this option is superfluous since you can specify a socks4a proxy -with --proxy using a socks4a:// protocol prefix. +This option is superfluous since you can specify a socks4a proxy with --proxy +using a socks4a:// protocol prefix. (Added in 7.21.7) Since 7.52.0, --preproxy can be used to specify a SOCKS proxy at the same time --proxy is used with an HTTP/HTTPS proxy. In such a case curl first connects to diff --git a/extern/curl/docs/cmdline-opts/socks5-basic.d b/extern/curl/docs/cmdline-opts/socks5-basic.d index 67d16b3a66..2e62bec5ad 100644 --- a/extern/curl/docs/cmdline-opts/socks5-basic.d +++ b/extern/curl/docs/cmdline-opts/socks5-basic.d @@ -1,6 +1,9 @@ Long: socks5-basic Help: Enable username/password auth for SOCKS5 proxies Added: 7.55.0 +Category: proxy auth +Example: --socks5-basic --socks5 hostname:4096 $URL +See-also: socks5 --- Tells curl to use username/password authentication when connecting to a SOCKS5 proxy. The username/password authentication is enabled by default. Use diff --git a/extern/curl/docs/cmdline-opts/socks5-gssapi-nec.d b/extern/curl/docs/cmdline-opts/socks5-gssapi-nec.d index 477e218e39..09166df22d 100644 --- a/extern/curl/docs/cmdline-opts/socks5-gssapi-nec.d +++ b/extern/curl/docs/cmdline-opts/socks5-gssapi-nec.d @@ -1,8 +1,11 @@ Long: socks5-gssapi-nec Help: Compatibility with NEC SOCKS5 server Added: 7.19.4 +Category: proxy auth +Example: --socks5-gssapi-nec --socks5 hostname:4096 $URL +See-also: socks5 --- As part of the GSS-API negotiation a protection mode is negotiated. RFC 1961 says in section 4.3/4.4 it should be protected, but the NEC reference -implementation does not. The option --socks5-gssapi-nec allows the +implementation does not. The option --socks5-gssapi-nec allows the unprotected exchange of the protection mode negotiation. diff --git a/extern/curl/docs/cmdline-opts/socks5-gssapi-service.d b/extern/curl/docs/cmdline-opts/socks5-gssapi-service.d index eb3b2407b3..5ce82ac3a4 100644 --- a/extern/curl/docs/cmdline-opts/socks5-gssapi-service.d +++ b/extern/curl/docs/cmdline-opts/socks5-gssapi-service.d @@ -2,6 +2,9 @@ Long: socks5-gssapi-service Arg: Help: SOCKS5 proxy service name for GSS-API Added: 7.19.4 +Category: proxy auth +Example: --socks5-gssapi-service sockd --socks5 hostname:4096 $URL +See-also: socks5 --- The default service name for a socks server is rcmd/server-fqdn. This option allows you to change it. diff --git a/extern/curl/docs/cmdline-opts/socks5-gssapi.d b/extern/curl/docs/cmdline-opts/socks5-gssapi.d index 0070f37eb2..6620940204 100644 --- a/extern/curl/docs/cmdline-opts/socks5-gssapi.d +++ b/extern/curl/docs/cmdline-opts/socks5-gssapi.d @@ -1,6 +1,9 @@ Long: socks5-gssapi Help: Enable GSS-API auth for SOCKS5 proxies Added: 7.55.0 +Category: proxy auth +Example: --socks5-gssapi --socks5 hostname:4096 $URL +See-also: socks5 --- Tells curl to use GSS-API authentication when connecting to a SOCKS5 proxy. The GSS-API authentication is enabled by default (if curl is compiled with diff --git a/extern/curl/docs/cmdline-opts/socks5-hostname.d b/extern/curl/docs/cmdline-opts/socks5-hostname.d index 9d9d946e57..6530429a9e 100644 --- a/extern/curl/docs/cmdline-opts/socks5-hostname.d +++ b/extern/curl/docs/cmdline-opts/socks5-hostname.d @@ -2,6 +2,9 @@ Long: socks5-hostname Arg: Help: SOCKS5 proxy, pass host name to proxy Added: 7.18.0 +Category: proxy +Example: --socks5-hostname proxy.example:7000 $URL +See-also: socks5 socks4a --- Use the specified SOCKS5 proxy (and let the proxy resolve the host name). If the port number is not specified, it is assumed at port 1080. @@ -9,8 +12,8 @@ the port number is not specified, it is assumed at port 1080. This option overrides any previous use of --proxy, as they are mutually exclusive. -Since 7.21.7, this option is superfluous since you can specify a socks5 -hostname proxy with --proxy using a socks5h:// protocol prefix. +This option is superfluous since you can specify a socks5 hostname proxy with +--proxy using a socks5h:// protocol prefix. (Added in 7.21.7) Since 7.52.0, --preproxy can be used to specify a SOCKS proxy at the same time --proxy is used with an HTTP/HTTPS proxy. In such a case curl first connects to diff --git a/extern/curl/docs/cmdline-opts/socks5.d b/extern/curl/docs/cmdline-opts/socks5.d index 22fae76295..af1c057712 100644 --- a/extern/curl/docs/cmdline-opts/socks5.d +++ b/extern/curl/docs/cmdline-opts/socks5.d @@ -2,6 +2,9 @@ Long: socks5 Arg: Help: SOCKS5 proxy on given host + port Added: 7.18.0 +Category: proxy +Example: --socks5 proxy.example:7000 $URL +See-also: socks5-hostname socks4a --- Use the specified SOCKS5 proxy - but resolve the host name locally. If the port number is not specified, it is assumed at port 1080. @@ -9,8 +12,8 @@ port number is not specified, it is assumed at port 1080. This option overrides any previous use of --proxy, as they are mutually exclusive. -Since 7.21.7, this option is superfluous since you can specify a socks5 proxy -with --proxy using a socks5:// protocol prefix. +This option is superfluous since you can specify a socks5 proxy with --proxy +using a socks5:// protocol prefix. (Added in 7.21.7) Since 7.52.0, --preproxy can be used to specify a SOCKS proxy at the same time --proxy is used with an HTTP/HTTPS proxy. In such a case curl first connects to diff --git a/extern/curl/docs/cmdline-opts/speed-limit.d b/extern/curl/docs/cmdline-opts/speed-limit.d index e2b81c79a3..c07b1d760f 100644 --- a/extern/curl/docs/cmdline-opts/speed-limit.d +++ b/extern/curl/docs/cmdline-opts/speed-limit.d @@ -2,6 +2,10 @@ Long: speed-limit Short: Y Arg: Help: Stop transfers slower than this +Category: connection +Example: --speed-limit 300 --speed-time 10 $URL +Added: 4.7 +See-also: speed-time limit-rate max-time --- If a download is slower than this given speed (in bytes per second) for speed-time seconds it gets aborted. speed-time is set with --speed-time and is diff --git a/extern/curl/docs/cmdline-opts/speed-time.d b/extern/curl/docs/cmdline-opts/speed-time.d index 98d6ae13c5..89cba59b60 100644 --- a/extern/curl/docs/cmdline-opts/speed-time.d +++ b/extern/curl/docs/cmdline-opts/speed-time.d @@ -2,6 +2,10 @@ Long: speed-time Short: y Arg: Help: Trigger 'speed-limit' abort after this time +Category: connection +Example: --speed-limit 300 --speed-time 10 $URL +Added: 4.7 +See-also: speed-limit limit-rate --- If a download is slower than speed-limit bytes per second during a speed-time period, the download gets aborted. If speed-time is used, the default diff --git a/extern/curl/docs/cmdline-opts/ssl-allow-beast.d b/extern/curl/docs/cmdline-opts/ssl-allow-beast.d index 973fcd4518..5a7fe995fc 100644 --- a/extern/curl/docs/cmdline-opts/ssl-allow-beast.d +++ b/extern/curl/docs/cmdline-opts/ssl-allow-beast.d @@ -1,9 +1,14 @@ Long: ssl-allow-beast Help: Allow security flaw to improve interop Added: 7.25.0 +Category: tls +Example: --ssl-allow-beast $URL +See-also: proxy-ssl-allow-beast insecure --- This option tells curl to not work around a security flaw in the SSL3 and -TLS1.0 protocols known as BEAST. If this option isn't used, the SSL layer may -use workarounds known to cause interoperability problems with some older SSL -implementations. WARNING: this option loosens the SSL security, and by using -this flag you ask for exactly that. +TLS1.0 protocols known as BEAST. If this option is not used, the SSL layer +may use workarounds known to cause interoperability problems with some older +SSL implementations. + +**WARNING**: this option loosens the SSL security, and by using this flag you +ask for exactly that. diff --git a/extern/curl/docs/cmdline-opts/ssl-auto-client-cert.d b/extern/curl/docs/cmdline-opts/ssl-auto-client-cert.d new file mode 100644 index 0000000000..7581bdff68 --- /dev/null +++ b/extern/curl/docs/cmdline-opts/ssl-auto-client-cert.d @@ -0,0 +1,13 @@ +Long: ssl-auto-client-cert +Help: Use auto client certificate (Schannel) +Added: 7.77.0 +See-also: proxy-ssl-auto-client-cert +Category: tls +Example: --ssl-auto-client-cert $URL +--- +Tell libcurl to automatically locate and use a client certificate for +authentication, when requested by the server. This option is only supported +for Schannel (the native Windows SSL library). Prior to 7.77.0 this was the +default behavior in libcurl with Schannel. Since the server can request any +certificate that supports client authentication in the OS certificate store it +could be a privacy violation and unexpected. diff --git a/extern/curl/docs/cmdline-opts/ssl-no-revoke.d b/extern/curl/docs/cmdline-opts/ssl-no-revoke.d index f94b111436..ba4b661f1a 100644 --- a/extern/curl/docs/cmdline-opts/ssl-no-revoke.d +++ b/extern/curl/docs/cmdline-opts/ssl-no-revoke.d @@ -1,6 +1,9 @@ Long: ssl-no-revoke Help: Disable cert revocation checks (Schannel) Added: 7.44.0 +Category: tls +Example: --ssl-no-revoke $URL +See-also: crlfile --- (Schannel) This option tells curl to disable certificate revocation checks. WARNING: this option loosens the SSL security, and by using this flag you ask diff --git a/extern/curl/docs/cmdline-opts/ssl-reqd.d b/extern/curl/docs/cmdline-opts/ssl-reqd.d index 3c6f8a257b..f8f23c9a05 100644 --- a/extern/curl/docs/cmdline-opts/ssl-reqd.d +++ b/extern/curl/docs/cmdline-opts/ssl-reqd.d @@ -1,9 +1,16 @@ Long: ssl-reqd Help: Require SSL/TLS -Protocols: FTP IMAP POP3 SMTP +Protocols: FTP IMAP POP3 SMTP LDAP Added: 7.20.0 +Category: tls +Example: --ssl-reqd ftp://example.com +See-also: ssl insecure --- -Require SSL/TLS for the connection. Terminates the connection if the server -doesn't support SSL/TLS. +Require SSL/TLS for the connection. Terminates the connection if the server +does not support SSL/TLS. + +This option is handled in LDAP since version 7.81.0. It is fully supported +by the openldap backend and rejected by the generic ldap backend if explicit +TLS is required. This option was formerly known as --ftp-ssl-reqd. diff --git a/extern/curl/docs/cmdline-opts/ssl-revoke-best-effort.d b/extern/curl/docs/cmdline-opts/ssl-revoke-best-effort.d new file mode 100644 index 0000000000..aad3ab0b4c --- /dev/null +++ b/extern/curl/docs/cmdline-opts/ssl-revoke-best-effort.d @@ -0,0 +1,10 @@ +Long: ssl-revoke-best-effort +Help: Ignore missing/offline cert CRL dist points +Added: 7.70.0 +Category: tls +Example: --ssl-revoke-best-effort $URL +See-also: crlfile insecure +--- +(Schannel) This option tells curl to ignore certificate revocation checks when +they failed due to missing/offline distribution points for the revocation check +lists. diff --git a/extern/curl/docs/cmdline-opts/ssl.d b/extern/curl/docs/cmdline-opts/ssl.d index dabd83761f..83cac5c9d6 100644 --- a/extern/curl/docs/cmdline-opts/ssl.d +++ b/extern/curl/docs/cmdline-opts/ssl.d @@ -1,12 +1,20 @@ Long: ssl Help: Try SSL/TLS -Protocols: FTP IMAP POP3 SMTP +Protocols: FTP IMAP POP3 SMTP LDAP Added: 7.20.0 +Category: tls +Example: --ssl pop3://example.com/ +See-also: insecure ciphers --- - -Try to use SSL/TLS for the connection. Reverts to a non-secure connection if -the server doesn't support SSL/TLS. See also --ftp-ssl-control and --ssl-reqd +Try to use SSL/TLS for the connection. Reverts to a non-secure connection if +the server does not support SSL/TLS. See also --ftp-ssl-control and --ssl-reqd for different levels of encryption required. +This option is handled in LDAP since version 7.81.0. It is fully supported +by the openldap backend and ignored by the generic ldap backend. + +Please note that a server may close the connection if the negotiation does +not succeed. + This option was formerly known as --ftp-ssl (Added in 7.11.0). That option name can still be used but will be removed in a future version. diff --git a/extern/curl/docs/cmdline-opts/sslv2.d b/extern/curl/docs/cmdline-opts/sslv2.d index 67d2b85065..f905964490 100644 --- a/extern/curl/docs/cmdline-opts/sslv2.d +++ b/extern/curl/docs/cmdline-opts/sslv2.d @@ -2,12 +2,14 @@ Short: 2 Long: sslv2 Tags: Versions Protocols: SSL -Added: +Added: 5.9 Mutexed: sslv3 tlsv1 tlsv1.1 tlsv1.2 Requires: TLS See-also: http1.1 http2 Help: Use SSLv2 +Category: tls +Example: --sslv2 $URL --- -Forces curl to use SSL version 2 when negotiating with a remote SSL -server. Sometimes curl is built without SSLv2 support. SSLv2 is widely -considered insecure (see RFC 6176). +This option previously asked curl to use SSLv2, but starting in curl 7.77.0 +this instruction is ignored. SSLv2 is widely considered insecure (see RFC +6176). diff --git a/extern/curl/docs/cmdline-opts/sslv3.d b/extern/curl/docs/cmdline-opts/sslv3.d index 101ad10047..6599531ce3 100644 --- a/extern/curl/docs/cmdline-opts/sslv3.d +++ b/extern/curl/docs/cmdline-opts/sslv3.d @@ -2,12 +2,14 @@ Short: 3 Long: sslv3 Tags: Versions Protocols: SSL -Added: +Added: 5.9 Mutexed: sslv2 tlsv1 tlsv1.1 tlsv1.2 Requires: TLS See-also: http1.1 http2 Help: Use SSLv3 +Category: tls +Example: --sslv3 $URL --- -Forces curl to use SSL version 3 when negotiating with a remote SSL -server. Sometimes curl is built without SSLv3 support. SSLv3 is widely -considered insecure (see RFC 7568). +This option previously asked curl to use SSLv3, but starting in curl 7.77.0 +this instruction is ignored. SSLv3 is widely considered insecure (see RFC +7568). diff --git a/extern/curl/docs/cmdline-opts/stderr.d b/extern/curl/docs/cmdline-opts/stderr.d index e8cf7ba68f..95b6604543 100644 --- a/extern/curl/docs/cmdline-opts/stderr.d +++ b/extern/curl/docs/cmdline-opts/stderr.d @@ -1,8 +1,15 @@ Long: stderr +Arg: Help: Where to redirect stderr See-also: verbose silent +Category: verbose +Example: --stderr output.txt $URL +Added: 6.2 --- Redirect all writes to stderr to the specified file instead. If the file name is a plain '-', it is instead written to stdout. +This option is global and does not need to be specified for each use of +--next. + If this option is used several times, the last one will be used. diff --git a/extern/curl/docs/cmdline-opts/styled-output.d b/extern/curl/docs/cmdline-opts/styled-output.d index e4751aecb1..364a182442 100644 --- a/extern/curl/docs/cmdline-opts/styled-output.d +++ b/extern/curl/docs/cmdline-opts/styled-output.d @@ -1,6 +1,12 @@ Long: styled-output Help: Enable styled output for HTTP headers Added: 7.61.0 +Category: verbose +Example: --styled-output -I $URL +See-also: head verbose --- Enables the automatic use of bold font styles when writing HTTP headers to the terminal. Use --no-styled-output to switch them off. + +This option is global and does not need to be specified for each use of +--next. diff --git a/extern/curl/docs/cmdline-opts/suppress-connect-headers.d b/extern/curl/docs/cmdline-opts/suppress-connect-headers.d index d208b89177..de465623be 100644 --- a/extern/curl/docs/cmdline-opts/suppress-connect-headers.d +++ b/extern/curl/docs/cmdline-opts/suppress-connect-headers.d @@ -1,8 +1,11 @@ Long: suppress-connect-headers Help: Suppress proxy CONNECT response headers See-also: dump-header include proxytunnel +Category: proxy +Example: --suppress-connect-headers --include -x proxy $URL +Added: 7.54.0 --- -When --proxytunnel is used and a CONNECT request is made don't output proxy +When --proxytunnel is used and a CONNECT request is made do not output proxy CONNECT response headers. This option is meant to be used with --dump-header or --include which are used to show protocol headers in the output. It has no effect on debug options such as --verbose or --trace, or any statistics. diff --git a/extern/curl/docs/cmdline-opts/tcp-fastopen.d b/extern/curl/docs/cmdline-opts/tcp-fastopen.d index 08e141df78..7b96b2d81a 100644 --- a/extern/curl/docs/cmdline-opts/tcp-fastopen.d +++ b/extern/curl/docs/cmdline-opts/tcp-fastopen.d @@ -1,5 +1,8 @@ Long: tcp-fastopen Added: 7.49.0 Help: Use TCP Fast Open +Category: connection +Example: --tcp-fastopen $URL +See-also: false-start --- Enable use of TCP Fast Open (RFC7413). diff --git a/extern/curl/docs/cmdline-opts/tcp-nodelay.d b/extern/curl/docs/cmdline-opts/tcp-nodelay.d index f047a7c6fa..a819b27fbd 100644 --- a/extern/curl/docs/cmdline-opts/tcp-nodelay.d +++ b/extern/curl/docs/cmdline-opts/tcp-nodelay.d @@ -1,9 +1,12 @@ Long: tcp-nodelay Help: Use the TCP_NODELAY option Added: 7.11.2 +Category: connection +Example: --tcp-nodelay $URL +See-also: no-buffer --- -Turn on the TCP_NODELAY option. See the \fIcurl_easy_setopt(3)\fP man page for +Turn on the TCP_NODELAY option. See the *curl_easy_setopt(3)* man page for details about this option. Since 7.50.2, curl sets this option by default and you need to explicitly -switch it off if you don't want it on. +switch it off if you do not want it on. diff --git a/extern/curl/docs/cmdline-opts/telnet-option.d b/extern/curl/docs/cmdline-opts/telnet-option.d index a67cb627b8..50f0d4800d 100644 --- a/extern/curl/docs/cmdline-opts/telnet-option.d +++ b/extern/curl/docs/cmdline-opts/telnet-option.d @@ -2,6 +2,10 @@ Long: telnet-option Short: t Arg: Help: Set telnet option +Category: telnet +Example: -t TTYPE=vt100 telnet://example.com/ +Added: 7.7 +See-also: config --- Pass options to the telnet protocol. Supported options are: diff --git a/extern/curl/docs/cmdline-opts/tftp-blksize.d b/extern/curl/docs/cmdline-opts/tftp-blksize.d index c184328de0..c180569a4d 100644 --- a/extern/curl/docs/cmdline-opts/tftp-blksize.d +++ b/extern/curl/docs/cmdline-opts/tftp-blksize.d @@ -3,6 +3,9 @@ Arg: Help: Set TFTP BLKSIZE option Protocols: TFTP Added: 7.20.0 +Category: tftp +Example: --tftp-blksize 1024 tftp://example.com/file +See-also: tftp-no-options --- Set TFTP BLKSIZE option (must be >512). This is the block size that curl will try to use when transferring data to or from a TFTP server. By default 512 diff --git a/extern/curl/docs/cmdline-opts/tftp-no-options.d b/extern/curl/docs/cmdline-opts/tftp-no-options.d index e2a4dacd52..a90655a023 100644 --- a/extern/curl/docs/cmdline-opts/tftp-no-options.d +++ b/extern/curl/docs/cmdline-opts/tftp-no-options.d @@ -2,6 +2,9 @@ Long: tftp-no-options Help: Do not send any TFTP options Protocols: TFTP Added: 7.48.0 +Category: tftp +Example: --tftp-no-options tftp://192.168.0.1/ +See-also: tftp-blksize --- Tells curl not to send TFTP options requests. diff --git a/extern/curl/docs/cmdline-opts/time-cond.d b/extern/curl/docs/cmdline-opts/time-cond.d index 830b4e1a24..602d66849c 100644 --- a/extern/curl/docs/cmdline-opts/time-cond.d +++ b/extern/curl/docs/cmdline-opts/time-cond.d @@ -3,12 +3,18 @@ Short: z Arg: