diff options
33 files changed, 1131 insertions, 530 deletions
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 7bb65dced4..03865b14ac 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -53,7 +53,7 @@ Files: ./icon.png ./logo.svg Comment: Godot Engine logo Copyright: 2017, Andrea CalabrĂ³ -License: CC-BY-3.0 +License: CC-BY-4.0 Files: ./platform/android/java/aidl/com/android/vending/billing/IInAppBillingService.aidl ./platform/android/java/res/layout/status_bar_ongoing_event_progress_bar.xml @@ -548,340 +548,317 @@ License: BSL-1.0 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -License: CC-BY-3.0 - Creative Commons Attribution 3.0 Unported +License: CC-BY-4.0 + Creative Commons Attribution 4.0 International Public License + . + By exercising the Licensed Rights (defined below), You accept and agree + to be bound by the terms and conditions of this Creative Commons + Attribution 4.0 International Public License ("Public + License"). To the extent this Public License may be interpreted as a + contract, You are granted the Licensed Rights in consideration of Your + acceptance of these terms and conditions, and the Licensor grants You + such rights in consideration of benefits the Licensor receives from + making the Licensed Material available under these terms and + conditions. + . + Section 1 -- Definitions. + . + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + . + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + . + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + . + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + . + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + . + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + . + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + . + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + . + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + . + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + . + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + . + Section 2 -- Scope. + . + a. License grant. + . + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + . + a. reproduce and Share the Licensed Material, in whole or + in part; and + . + b. produce, reproduce, and Share Adapted Material. + . + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + . + 3. Term. The term of this Public License is specified in Section + 6(a). + . + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + . + 5. Downstream recipients. + . + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + . + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + . + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + . + b. Other rights. + . + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + . + 2. Patent and trademark rights are not licensed under this + Public License. + . + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + . + Section 3 -- License Conditions. + . + Your exercise of the Licensed Rights is expressly made subject to the + following conditions. + . + a. Attribution. + . + 1. If You Share the Licensed Material (including in modified + form), You must: + . + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + . + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + . + ii. a copyright notice; + . + iii. a notice that refers to this Public License; + . + iv. a notice that refers to the disclaimer of + warranties; + . + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + . + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + . + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + . + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + . + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + . + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + . + Section 4 -- Sui Generis Database Rights. + . + Where the Licensed Rights include Sui Generis Database Rights that + apply to Your use of the Licensed Material: + . + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + . + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + . + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + . + For the avoidance of doubt, this Section 4 supplements and does not + replace Your obligations under this Public License where the Licensed + Rights include other Copyright and Similar Rights. + . + Section 5 -- Disclaimer of Warranties and Limitation of Liability. + . + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. . - CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE - LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN - ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION - ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE - INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM - ITS USE. + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. . - License + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. . - THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE - COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY - COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS - AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + Section 6 -- Term and Termination. . - BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE - TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY - BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS - CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND - CONDITIONS. + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. . - 1. Definitions + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: . - a. "Adaptation" means a work based upon the Work, or upon the Work and - other pre-existing works, such as a translation, adaptation, derivative - work, arrangement of music or other alterations of a literary or - artistic work, or phonogram or performance and includes cinematographic - adaptations or any other form in which the Work may be recast, - transformed, or adapted including in any form recognizably derived from - the original, except that a work that constitutes a Collection will not - be considered an Adaptation for the purpose of this License. For the - avoidance of doubt, where the Work is a musical work, performance or - phonogram, the synchronization of the Work in timed-relation with a - moving image ("synching") will be considered an Adaptation for the - purpose of this License. - . - b. "Collection" means a collection of literary or artistic works, such - as encyclopedias and anthologies, or performances, phonograms or - broadcasts, or other works or subject matter other than works listed in - Section 1(f) below, which, by reason of the selection and arrangement of - their contents, constitute intellectual creations, in which the Work is - included in its entirety in unmodified form along with one or more other - contributions, each constituting separate and independent works in - themselves, which together are assembled into a collective whole. A work - that constitutes a Collection will not be considered an Adaptation (as - defined above) for the purposes of this License. - . - c. "Distribute" means to make available to the public the original and - copies of the Work or Adaptation, as appropriate, through sale or other - transfer of ownership. - . - d. "Licensor" means the individual, individuals, entity or entities that - offer(s) the Work under the terms of this License. - . - e. "Original Author" means, in the case of a literary or artistic work, - the individual, individuals, entity or entities who created the Work or - if no individual or entity can be identified, the publisher; and in - addition (i) in the case of a performance the actors, singers, - musicians, dancers, and other persons who act, sing, deliver, declaim, - play in, interpret or otherwise perform literary or artistic works or - expressions of folklore; (ii) in the case of a phonogram the producer - being the person or legal entity who first fixes the sounds of a - performance or other sounds; and, (iii) in the case of broadcasts, the - organization that transmits the broadcast. - . - f. "Work" means the literary and/or artistic work offered under the - terms of this License including without limitation any production in the - literary, scientific and artistic domain, whatever may be the mode or - form of its expression including digital form, such as a book, pamphlet - and other writing; a lecture, address, sermon or other work of the same - nature; a dramatic or dramatico-musical work; a choreographic work or - entertainment in dumb show; a musical composition with or without words; - a cinematographic work to which are assimilated works expressed by a - process analogous to cinematography; a work of drawing, painting, - architecture, sculpture, engraving or lithography; a photographic work - to which are assimilated works expressed by a process analogous to - photography; a work of applied art; an illustration, map, plan, sketch - or three-dimensional work relative to geography, topography, - architecture or science; a performance; a broadcast; a phonogram; a - compilation of data to the extent it is protected as a copyrightable - work; or a work performed by a variety or circus performer to the extent - it is not otherwise considered a literary or artistic work. - . - g. "You" means an individual or entity exercising rights under this - License who has not previously violated the terms of this License with - respect to the Work, or who has received express permission from the - Licensor to exercise rights under this License despite a previous - violation. - . - h. "Publicly Perform" means to perform public recitations of the Work - and to communicate to the public those public recitations, by any means - or process, including by wire or wireless means or public digital - performances; to make available to the public Works in such a way that - members of the public may access these Works from a place and at a place - individually chosen by them; to perform the Work to the public by any - means or process and the communication to the public of the performances - of the Work, including by public digital performance; to broadcast and - rebroadcast the Work by any means including signs, sounds or images. - . - i. "Reproduce" means to make copies of the Work by any means including - without limitation by sound or visual recordings and the right of - fixation and reproducing fixations of the Work, including storage of a - protected performance or phonogram in digital form or other electronic - medium. - . - 2. Fair Dealing Rights. Nothing in this License is intended to reduce, - limit, or restrict any uses free from copyright or rights arising from - limitations or exceptions that are provided for in connection with the - copyright protection under copyright law or other applicable laws. - . - 3. License Grant. Subject to the terms and conditions of this License, - Licensor hereby grants You a worldwide, royalty-free, non-exclusive, - perpetual (for the duration of the applicable copyright) license to - exercise the rights in the Work as stated below: - . - a. to Reproduce the Work, to incorporate the Work into one or more - Collections, and to Reproduce the Work as incorporated in the - Collections; - . - b. to create and Reproduce Adaptations provided that any such - Adaptation, including any translation in any medium, takes reasonable - steps to clearly label, demarcate or otherwise identify that changes - were made to the original Work. For example, a translation could be - marked "The original work was translated from English to Spanish," or a - modification could indicate "The original work has been modified."; - . - c. to Distribute and Publicly Perform the Work including as incorporated - in Collections; and, - . - d. to Distribute and Publicly Perform Adaptations. - . - e. For the avoidance of doubt: - . - i. Non-waivable Compulsory License Schemes. In those jurisdictions in - which the right to collect royalties through any statutory or compulsory - licensing scheme cannot be waived, the Licensor reserves the exclusive - right to collect such royalties for any exercise by You of the rights - granted under this License; - . - ii. Waivable Compulsory License Schemes. In those jurisdictions in which - the right to collect royalties through any statutory or compulsory - licensing scheme can be waived, the Licensor waives the exclusive right - to collect such royalties for any exercise by You of the rights granted - under this License; and, - . - iii. Voluntary License Schemes. The Licensor waives the right to collect - royalties, whether individually or, in the event that the Licensor is a - member of a collecting society that administers voluntary licensing - schemes, via that society, from any exercise by You of the rights - granted under this License. - . - The above rights may be exercised in all media and formats whether now - known or hereafter devised. The above rights include the right to make - such modifications as are technically necessary to exercise the rights - in other media and formats. Subject to Section 8(f), all rights not - expressly granted by Licensor are hereby reserved. - . - 4. Restrictions. The license granted in Section 3 above is expressly - made subject to and limited by the following restrictions: - . - a. You may Distribute or Publicly Perform the Work only under the terms - of this License. You must include a copy of, or the Uniform Resource - Identifier (URI) for, this License with every copy of the Work You - Distribute or Publicly Perform. You may not offer or impose any terms on - the Work that restrict the terms of this License or the ability of the - recipient of the Work to exercise the rights granted to that recipient - under the terms of the License. You may not sublicense the Work. You - must keep intact all notices that refer to this License and to the - disclaimer of warranties with every copy of the Work You Distribute or - Publicly Perform. When You Distribute or Publicly Perform the Work, You - may not impose any effective technological measures on the Work that - restrict the ability of a recipient of the Work from You to exercise the - rights granted to that recipient under the terms of the License. This - Section 4(a) applies to the Work as incorporated in a Collection, but - this does not require the Collection apart from the Work itself to be - made subject to the terms of this License. If You create a Collection, - upon notice from any Licensor You must, to the extent practicable, - remove from the Collection any credit as required by Section 4(b), as - requested. If You create an Adaptation, upon notice from any Licensor - You must, to the extent practicable, remove from the Adaptation any - credit as required by Section 4(b), as requested. - . - b. If You Distribute, or Publicly Perform the Work or any Adaptations or - Collections, You must, unless a request has been made pursuant to - Section 4(a), keep intact all copyright notices for the Work and - provide, reasonable to the medium or means You are utilizing: (i) the - name of the Original Author (or pseudonym, if applicable) if supplied, - and/or if the Original Author and/or Licensor designate another party or - parties (e.g., a sponsor institute, publishing entity, journal) for - attribution ("Attribution Parties") in Licensor's copyright notice, - terms of service or by other reasonable means, the name of such party or - parties; (ii) the title of the Work if supplied; (iii) to the extent - reasonably practicable, the URI, if any, that Licensor specifies to be - associated with the Work, unless such URI does not refer to the - copyright notice or licensing information for the Work; and (iv) , - consistent with Section 3(b), in the case of an Adaptation, a credit - identifying the use of the Work in the Adaptation (e.g., "French - translation of the Work by Original Author," or "Screenplay based on - original Work by Original Author"). The credit required by this Section - 4 (b) may be implemented in any reasonable manner; provided, however, - that in the case of a Adaptation or Collection, at a minimum such credit - will appear, if a credit for all contributing authors of the Adaptation - or Collection appears, then as part of these credits and in a manner at - least as prominent as the credits for the other contributing authors. - For the avoidance of doubt, You may only use the credit required by this - Section for the purpose of attribution in the manner set out above and, - by exercising Your rights under this License, You may not implicitly or - explicitly assert or imply any connection with, sponsorship or - endorsement by the Original Author, Licensor and/or Attribution Parties, - as appropriate, of You or Your use of the Work, without the separate, - express prior written permission of the Original Author, Licensor and/or - Attribution Parties. - . - c. Except as otherwise agreed in writing by the Licensor or as may be - otherwise permitted by applicable law, if You Reproduce, Distribute or - Publicly Perform the Work either by itself or as part of any Adaptations - or Collections, You must not distort, mutilate, modify or take other - derogatory action in relation to the Work which would be prejudicial to - the Original Author's honor or reputation. Licensor agrees that in those - jurisdictions (e.g. Japan), in which any exercise of the right granted - in Section 3(b) of this License (the right to make Adaptations) would be - deemed to be a distortion, mutilation, modification or other derogatory - action prejudicial to the Original Author's honor and reputation, the - Licensor will waive or not assert, as appropriate, this Section, to the - fullest extent permitted by the applicable national law, to enable You - to reasonably exercise Your right under Section 3(b) of this License - (right to make Adaptations) but not otherwise. - . - 5. Representations, Warranties and Disclaimer - . - UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR - OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY - KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, - INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, - FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF - LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, - WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE - EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. - . - 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE - LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR - ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES - ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS - BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - . - 7. Termination - . - a. This License and the rights granted hereunder will terminate - automatically upon any breach by You of the terms of this License. - Individuals or entities who have received Adaptations or Collections - from You under this License, however, will not have their licenses - terminated provided such individuals or entities remain in full - compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will - survive any termination of this License. - . - b. Subject to the above terms and conditions, the license granted here - is perpetual (for the duration of the applicable copyright in the Work). - Notwithstanding the above, Licensor reserves the right to release the - Work under different license terms or to stop distributing the Work at - any time; provided, however that any such election will not serve to - withdraw this License (or any other license that has been, or is - required to be, granted under the terms of this License), and this - License will continue in full force and effect unless terminated as - stated above. - . - 8. Miscellaneous - . - a. Each time You Distribute or Publicly Perform the Work or a - Collection, the Licensor offers to the recipient a license to the Work - on the same terms and conditions as the license granted to You under - this License. - . - b. Each time You Distribute or Publicly Perform an Adaptation, Licensor - offers to the recipient a license to the original Work on the same terms - and conditions as the license granted to You under this License. - . - c. If any provision of this License is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability of - the remainder of the terms of this License, and without further action - by the parties to this agreement, such provision shall be reformed to - the minimum extent necessary to make such provision valid and - enforceable. - . - d. No term or provision of this License shall be deemed waived and no - breach consented to unless such waiver or consent shall be in writing - and signed by the party to be charged with such waiver or consent. This - License constitutes the entire agreement between the parties with - respect to the Work licensed here. There are no understandings, - agreements or representations with respect to the Work not specified - here. Licensor shall not be bound by any additional provisions that may - appear in any communication from You. - . - e. This License may not be modified without the mutual written agreement - of the Licensor and You. - . - f. The rights granted under, and the subject matter referenced, in this - License were drafted utilizing the terminology of the Berne Convention - for the Protection of Literary and Artistic Works (as amended on - September 28, 1979), the Rome Convention of 1961, the WIPO Copyright - Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and - the Universal Copyright Convention (as revised on July 24, 1971). These - rights and subject matter take effect in the relevant jurisdiction in - which the License terms are sought to be enforced according to the - corresponding provisions of the implementation of those treaty - provisions in the applicable national law. If the standard suite of - rights granted under applicable copyright law includes additional rights - not granted under this License, such additional rights are deemed to be - included in the License; this License is not intended to restrict the - license of any rights under applicable law. - . - Creative Commons Notice - . - Creative Commons is not a party to this License, and makes no warranty - whatsoever in connection with the Work. Creative Commons will not be - liable to You or any party on any legal theory for any damages - whatsoever, including without limitation any general, special, - incidental or consequential damages arising in connection to this - license. Notwithstanding the foregoing two (2) sentences, if Creative - Commons has expressly identified itself as the Licensor hereunder, it - shall have all rights and obligations of Licensor. - . - Except for the limited purpose of indicating to the public that the Work - is licensed under the CCPL, Creative Commons does not authorize the use - by either party of the trademark "Creative Commons" or any related - trademark or logo of Creative Commons without the prior written consent - of Creative Commons. Any permitted use will be in compliance with - Creative Commons' then-current trademark usage guidelines, as may be - published on its website or otherwise made available upon request from - time to time. For the avoidance of doubt, this trademark restriction - does not form part of this License. - . - Creative Commons may be contacted at http://creativecommons.org/. + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + . + 2. upon express reinstatement by the Licensor. + . + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + . + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + . + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + . + Section 7 -- Other Terms and Conditions. + . + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + . + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + . + Section 8 -- Interpretation. + . + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + . + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + . + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + . + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. License: Expat Permission is hereby granted, free of charge, to any person obtaining diff --git a/LOGO_LICENSE.md b/LOGO_LICENSE.md index b357c49664..52ee37fb2f 100644 --- a/LOGO_LICENSE.md +++ b/LOGO_LICENSE.md @@ -1,3 +1,5 @@ -Godot Logo (C) Andrea CalabrĂ³ -Distributed under the terms of the Creative Commons Attribution License -version 3.0 (CC-BY 3.0) <https://creativecommons.org/licenses/by/3.0/legalcode>. +Godot Engine Logo +Copyright (c) 2017 Andrea CalabrĂ³ + +This work is licensed under a Creative Commons Attribution 4.0 International +License (CC-BY-4.0 International) <https://creativecommons.org/licenses/by/4.0/>. diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp index d12108bca0..33ba0ba704 100644 --- a/core/crypto/crypto.cpp +++ b/core/crypto/crypto.cpp @@ -65,6 +65,22 @@ void X509Certificate::_bind_methods() { ClassDB::bind_method(D_METHOD("load", "path"), &X509Certificate::load); } +/// HMACContext + +void HMACContext::_bind_methods() { + ClassDB::bind_method(D_METHOD("start", "hash_type", "key"), &HMACContext::start); + ClassDB::bind_method(D_METHOD("update", "data"), &HMACContext::update); + ClassDB::bind_method(D_METHOD("finish"), &HMACContext::finish); +} + +HMACContext *(*HMACContext::_create)() = nullptr; +HMACContext *HMACContext::create() { + if (_create) { + return _create(); + } + ERR_FAIL_V_MSG(nullptr, "HMACContext is not available when the mbedtls module is disabled."); +} + /// Crypto void (*Crypto::_load_default_certificates)(String p_path) = nullptr; @@ -82,6 +98,35 @@ void Crypto::load_default_certificates(String p_path) { } } +PackedByteArray Crypto::hmac_digest(HashingContext::HashType p_hash_type, PackedByteArray p_key, PackedByteArray p_msg) { + Ref<HMACContext> ctx = Ref<HMACContext>(HMACContext::create()); + ERR_FAIL_COND_V_MSG(ctx.is_null(), PackedByteArray(), "HMAC is not available witout mbedtls module."); + Error err = ctx->start(p_hash_type, p_key); + ERR_FAIL_COND_V(err != OK, PackedByteArray()); + err = ctx->update(p_msg); + ERR_FAIL_COND_V(err != OK, PackedByteArray()); + return ctx->finish(); +} + +// Compares two HMACS for equality without leaking timing information in order to prevent timing attakcs. +// @see: https://paragonie.com/blog/2015/11/preventing-timing-attacks-on-string-comparison-with-double-hmac-strategy +bool Crypto::constant_time_compare(PackedByteArray p_trusted, PackedByteArray p_received) { + const uint8_t *t = p_trusted.ptr(); + const uint8_t *r = p_received.ptr(); + int tlen = p_trusted.size(); + int rlen = p_received.size(); + // If the lengths are different then nothing else matters. + if (tlen != rlen) { + return false; + } + + uint8_t v = 0; + for (int i = 0; i < tlen; i++) { + v |= t[i] ^ r[i]; + } + return v == 0; +} + void Crypto::_bind_methods() { ClassDB::bind_method(D_METHOD("generate_random_bytes", "size"), &Crypto::generate_random_bytes); ClassDB::bind_method(D_METHOD("generate_rsa", "size"), &Crypto::generate_rsa); @@ -90,6 +135,8 @@ void Crypto::_bind_methods() { ClassDB::bind_method(D_METHOD("verify", "hash_type", "hash", "signature", "key"), &Crypto::verify); ClassDB::bind_method(D_METHOD("encrypt", "key", "plaintext"), &Crypto::encrypt); ClassDB::bind_method(D_METHOD("decrypt", "key", "ciphertext"), &Crypto::decrypt); + ClassDB::bind_method(D_METHOD("hmac_digest", "hash_type", "key", "msg"), &Crypto::hmac_digest); + ClassDB::bind_method(D_METHOD("constant_time_compare", "trusted", "received"), &Crypto::constant_time_compare); } /// Resource loader/saver diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h index 8325f043bf..5cacddaea0 100644 --- a/core/crypto/crypto.h +++ b/core/crypto/crypto.h @@ -67,6 +67,23 @@ public: virtual Error save(String p_path) = 0; }; +class HMACContext : public Reference { + GDCLASS(HMACContext, Reference); + +protected: + static void _bind_methods(); + static HMACContext *(*_create)(); + +public: + static HMACContext *create(); + + virtual Error start(HashingContext::HashType p_hash_type, PackedByteArray p_key) = 0; + virtual Error update(PackedByteArray p_data) = 0; + virtual PackedByteArray finish() = 0; + + HMACContext() {} +}; + class Crypto : public Reference { GDCLASS(Crypto, Reference); @@ -88,6 +105,12 @@ public: virtual Vector<uint8_t> encrypt(Ref<CryptoKey> p_key, Vector<uint8_t> p_plaintext) = 0; virtual Vector<uint8_t> decrypt(Ref<CryptoKey> p_key, Vector<uint8_t> p_ciphertext) = 0; + PackedByteArray hmac_digest(HashingContext::HashType p_hash_type, PackedByteArray p_key, PackedByteArray p_msg); + + // Compares two PackedByteArrays for equality without leaking timing information in order to prevent timing attacks. + // @see: https://paragonie.com/blog/2015/11/preventing-timing-attacks-on-string-comparison-with-double-hmac-strategy + bool constant_time_compare(PackedByteArray p_trusted, PackedByteArray p_received); + Crypto() {} }; diff --git a/core/input/input.cpp b/core/input/input.cpp index 00a7e63a73..153656e44a 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -1211,7 +1211,7 @@ void Input::parse_mapping(String p_mapping) { ERR_CONTINUE_MSG(output.length() < 1 || input.length() < 2, String(entry[idx] + "\nInvalid device mapping entry: " + entry[idx])); - if (output == "platform") { + if (output == "platform" || output == "hint") { continue; } diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 41bc5e84b0..e04e642f6b 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -84,10 +84,6 @@ Ref<InputEvent> InputEvent::xformed_by(const Transform2D &p_xform, const Vector2 return Ref<InputEvent>((InputEvent *)this); } -String InputEvent::as_text() const { - return String(); -} - bool InputEvent::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const { return false; } @@ -198,6 +194,33 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif set_metakey(event->get_metakey()); } +String InputEventWithModifiers::as_text() const { + Vector<String> mod_names; + + if (get_control()) { + mod_names.push_back(find_keycode_name(KEY_CONTROL)); + } + if (get_shift()) { + mod_names.push_back(find_keycode_name(KEY_SHIFT)); + } + if (get_alt()) { + mod_names.push_back(find_keycode_name(KEY_ALT)); + } + if (get_metakey()) { + mod_names.push_back(find_keycode_name(KEY_META)); + } + + if (!mod_names.empty()) { + return String("+").join(mod_names); + } else { + return "None"; + } +} + +String InputEventWithModifiers::to_string() { + return as_text(); +} + void InputEventWithModifiers::_bind_methods() { ClassDB::bind_method(D_METHOD("set_store_command", "enable"), &InputEventWithModifiers::set_store_command); ClassDB::bind_method(D_METHOD("is_storing_command"), &InputEventWithModifiers::is_storing_command); @@ -326,24 +349,31 @@ uint32_t InputEventKey::get_physical_keycode_with_modifiers() const { } String InputEventKey::as_text() const { - String kc = keycode_get_string(keycode); + String kc; + + if (keycode == 0) { + kc = keycode_get_string(physical_keycode) + " (" + RTR("Physical") + ")"; + } else { + kc = keycode_get_string(keycode); + } + if (kc == String()) { return kc; } - if (get_metakey()) { - kc = find_keycode_name(KEY_META) + ("+" + kc); - } - if (get_alt()) { - kc = find_keycode_name(KEY_ALT) + ("+" + kc); - } - if (get_shift()) { - kc = find_keycode_name(KEY_SHIFT) + ("+" + kc); - } - if (get_control()) { - kc = find_keycode_name(KEY_CONTROL) + ("+" + kc); + String mods_text = InputEventWithModifiers::as_text(); + return mods_text == "" ? kc : mods_text + "+" + kc; +} + +String InputEventKey::to_string() { + String p = is_pressed() ? "true" : "false"; + String e = is_echo() ? "true" : "false"; + + if (keycode == 0) { + return vformat("InputEventKey: keycode=%s mods=%s physical=%s pressed=%s echo=%s", itos(physical_keycode) + " " + keycode_get_string(physical_keycode), InputEventWithModifiers::as_text(), "true", p, e); + } else { + return vformat("InputEventKey: keycode=%s mods=%s physical=%s pressed=%s echo=%s", itos(keycode) + " " + keycode_get_string(keycode), InputEventWithModifiers::as_text(), "false", p, e); } - return kc; } bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const { @@ -536,41 +566,74 @@ bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool *p return match; } +static const char *_mouse_button_descriptions[9] = { + TTRC("Left Mouse Button"), + TTRC("Right Mouse Button"), + TTRC("Middle Mouse Button"), + TTRC("Mouse Wheel Up"), + TTRC("Mouse Wheel Down"), + TTRC("Mouse Wheel Left"), + TTRC("Mouse Wheel Right"), + TTRC("Mouse Thumb Button 1"), + TTRC("Mouse Thumb Button 2") +}; + String InputEventMouseButton::as_text() const { - String button_index_string = ""; - switch (get_button_index()) { + // Modifiers + String mods_text = InputEventWithModifiers::as_text(); + String full_string = mods_text == "" ? "" : mods_text + "+"; + + // Button + int idx = get_button_index(); + switch (idx) { case BUTTON_LEFT: - button_index_string = "BUTTON_LEFT"; - break; case BUTTON_RIGHT: - button_index_string = "BUTTON_RIGHT"; - break; case BUTTON_MIDDLE: - button_index_string = "BUTTON_MIDDLE"; - break; case BUTTON_WHEEL_UP: - button_index_string = "BUTTON_WHEEL_UP"; - break; case BUTTON_WHEEL_DOWN: - button_index_string = "BUTTON_WHEEL_DOWN"; - break; case BUTTON_WHEEL_LEFT: - button_index_string = "BUTTON_WHEEL_LEFT"; - break; case BUTTON_WHEEL_RIGHT: - button_index_string = "BUTTON_WHEEL_RIGHT"; - break; case BUTTON_XBUTTON1: - button_index_string = "BUTTON_XBUTTON1"; + case BUTTON_XBUTTON2: + full_string += RTR(_mouse_button_descriptions[idx - 1]); // button index starts from 1, array index starts from 0, so subtract 1 + break; + default: + full_string += RTR("Button") + " #" + itos(idx); break; + } + + // Double Click + if (doubleclick) { + full_string += " (" + RTR("Double Click") + ")"; + } + + return full_string; +} + +String InputEventMouseButton::to_string() { + String p = is_pressed() ? "true" : "false"; + String d = doubleclick ? "true" : "false"; + + int idx = get_button_index(); + String button_string = itos(idx); + + switch (idx) { + case BUTTON_LEFT: + case BUTTON_RIGHT: + case BUTTON_MIDDLE: + case BUTTON_WHEEL_UP: + case BUTTON_WHEEL_DOWN: + case BUTTON_WHEEL_LEFT: + case BUTTON_WHEEL_RIGHT: + case BUTTON_XBUTTON1: case BUTTON_XBUTTON2: - button_index_string = "BUTTON_XBUTTON2"; + button_string += " (" + RTR(_mouse_button_descriptions[idx - 1]) + ")"; // button index starts from 1, array index starts from 0, so subtract 1 break; default: - button_index_string = itos(get_button_index()); break; } - return "InputEventMouseButton : button_index=" + button_index_string + ", pressed=" + (pressed ? "true" : "false") + ", position=(" + String(get_position()) + "), button_mask=" + itos(get_button_mask()) + ", doubleclick=" + (doubleclick ? "true" : "false"); + + return vformat("InputEventMouseButton: button_index=%s pressed=%s position=(%s) button_mask=%s doubleclick=%s", button_index, p, String(get_position()), itos(get_button_mask()), d); } void InputEventMouseButton::_bind_methods() { @@ -653,27 +716,32 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co } String InputEventMouseMotion::as_text() const { - String button_mask_string = ""; + return vformat(RTR("Mouse motion at position (%s) with speed (%s)"), String(get_position()), String(get_speed())); +} + +String InputEventMouseMotion::to_string() { + int button_mask = get_button_mask(); + String button_mask_string = itos(button_mask); switch (get_button_mask()) { case BUTTON_MASK_LEFT: - button_mask_string = "BUTTON_MASK_LEFT"; + button_mask_string += " (" + RTR(_mouse_button_descriptions[BUTTON_LEFT - 1]) + ")"; break; case BUTTON_MASK_MIDDLE: - button_mask_string = "BUTTON_MASK_MIDDLE"; + button_mask_string += " (" + RTR(_mouse_button_descriptions[BUTTON_MIDDLE - 1]) + ")"; break; case BUTTON_MASK_RIGHT: - button_mask_string = "BUTTON_MASK_RIGHT"; + button_mask_string += " (" + RTR(_mouse_button_descriptions[BUTTON_RIGHT - 1]) + ")"; break; case BUTTON_MASK_XBUTTON1: - button_mask_string = "BUTTON_MASK_XBUTTON1"; + button_mask_string += " (" + RTR(_mouse_button_descriptions[BUTTON_XBUTTON1 - 1]) + ")"; break; case BUTTON_MASK_XBUTTON2: - button_mask_string = "BUTTON_MASK_XBUTTON2"; + button_mask_string += " (" + RTR(_mouse_button_descriptions[BUTTON_XBUTTON2 - 1]) + ")"; break; default: - button_mask_string = itos(get_button_mask()); break; } + return "InputEventMouseMotion : button_mask=" + button_mask_string + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + "), pressure=(" + rtos(get_pressure()) + "), tilt=(" + String(get_tilt()) + ")"; } @@ -796,7 +864,26 @@ bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool * return match; } +static const char *_joy_axis_descriptions[JOY_AXIS_MAX] = { + TTRC("Left Stick X-Axis, Joystick 0 X-Axis"), + TTRC("Left Stick Y-Axis, Joystick 0 Y-Axis"), + TTRC("Right Stick X-Axis, Joystick 1 X-Axis"), + TTRC("Right Stick Y-Axis, Joystick 1 Y-Axis"), + TTRC("Joystick 2 X-Axis, Left Trigger, Sony L2, Xbox LT"), + TTRC("Joystick 2 Y-Axis, Right Trigger, Sony R2, Xbox RT"), + TTRC("Joystick 3 X-Axis"), + TTRC("Joystick 3 Y-Axis"), + TTRC("Joystick 4 X-Axis"), + TTRC("Joystick 4 Y-Axis"), +}; + String InputEventJoypadMotion::as_text() const { + String desc = axis < JOY_AXIS_MAX ? RTR(_joy_axis_descriptions[axis]) : TTR("Unknown Joypad Axis"); + + return vformat(TTR("Joypad Motion on Axis %s (%s) with Value %s"), itos(axis), desc, String(Variant(axis_value))); +} + +String InputEventJoypadMotion::to_string() { return "InputEventJoypadMotion : axis=" + itos(axis) + ", axis_value=" + String(Variant(axis_value)); } @@ -869,7 +956,39 @@ bool InputEventJoypadButton::shortcut_match(const Ref<InputEvent> &p_event) cons return button_index == button->button_index; } +static const char *_joy_button_descriptions[JOY_BUTTON_SDL_MAX] = { + TTRC("Bottom Action, Sony Cross, Xbox A, Nintendo B"), + TTRC("Right Action, Sony Circle, Xbox B, Nintendo A"), + TTRC("Left Action, Sony Square, Xbox X, Nintendo Y"), + TTRC("Top Action, Sony Triangle, Xbox Y, Nintendo X"), + TTRC("Back, Sony Select, Xbox Back, Nintendo -"), + TTRC("Guide, Sony PS, Xbox Home"), + TTRC("Start, Nintendo +"), + TTRC("Left Stick, Sony L3, Xbox L/LS"), + TTRC("Right Stick, Sony R3, Xbox R/RS"), + TTRC("Left Shoulder, Sony L1, Xbox LB"), + TTRC("Right Shoulder, Sony R1, Xbox RB"), + TTRC("D-pad Up"), + TTRC("D-pad Down"), + TTRC("D-pad Left"), + TTRC("D-pad Right"), +}; + String InputEventJoypadButton::as_text() const { + String text = "Joypad Button " + itos(button_index); + + if (button_index < JOY_BUTTON_SDL_MAX) { + text += vformat(" (%s)", _joy_button_descriptions[button_index]); + } + + if (pressure != 0) { + text += ", Pressure:" + String(Variant(pressure)); + } + + return text; +} + +String InputEventJoypadButton::to_string() { return "InputEventJoypadButton : button_index=" + itos(button_index) + ", pressed=" + (pressed ? "true" : "false") + ", pressure=" + String(Variant(pressure)); } @@ -927,6 +1046,12 @@ Ref<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, co } String InputEventScreenTouch::as_text() const { + String status = pressed ? RTR("touched") : RTR("released"); + + return vformat(RTR("Screen %s at (%s) with %s touch points"), status, String(get_position()), itos(index)); +} + +String InputEventScreenTouch::to_string() { return "InputEventScreenTouch : index=" + itos(index) + ", pressed=" + (pressed ? "true" : "false") + ", position=(" + String(get_position()) + ")"; } @@ -996,6 +1121,10 @@ Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, con } String InputEventScreenDrag::as_text() const { + return vformat(RTR("Screen dragged with %s touch points at position (%s) with speed of (%s)"), itos(index), String(get_position()), String(get_speed())); +} + +String InputEventScreenDrag::to_string() { return "InputEventScreenDrag : index=" + itos(index) + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + ")"; } @@ -1079,6 +1208,10 @@ bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pres } String InputEventAction::as_text() const { + return vformat(RTR("Input Action %s was %s"), action, pressed ? "pressed" : "released"); +} + +String InputEventAction::to_string() { return "InputEventAction : action=" + action + ", pressed=(" + (pressed ? "true" : "false"); } @@ -1142,6 +1275,10 @@ Ref<InputEvent> InputEventMagnifyGesture::xformed_by(const Transform2D &p_xform, } String InputEventMagnifyGesture::as_text() const { + return vformat(RTR("Magnify Gesture at (%s) with factor %s"), String(get_position()), rtos(get_factor())); +} + +String InputEventMagnifyGesture::to_string() { return "InputEventMagnifyGesture : factor=" + rtos(get_factor()) + ", position=(" + String(get_position()) + ")"; } @@ -1178,6 +1315,10 @@ Ref<InputEvent> InputEventPanGesture::xformed_by(const Transform2D &p_xform, con } String InputEventPanGesture::as_text() const { + return vformat(RTR("Pan Gesture at (%s) with delta (%s)"), String(get_position()), String(get_delta())); +} + +String InputEventPanGesture::to_string() { return "InputEventPanGesture : delta=(" + String(get_delta()) + "), position=(" + String(get_position()) + ")"; } @@ -1255,7 +1396,11 @@ int InputEventMIDI::get_controller_value() const { } String InputEventMIDI::as_text() const { - return "InputEventMIDI : channel=(" + itos(get_channel()) + "), message=(" + itos(get_message()) + ")"; + return vformat(RTR("MIDI Input on Channel=%s Message=%s"), itos(channel), itos(message)); +} + +String InputEventMIDI::to_string() { + return vformat("InputEvenMIDI: channel=%s message=%s pitch=%s velocity=%s pressure=%s", itos(channel), itos(message), itos(pitch), itos(velocity), itos(pressure)); } void InputEventMIDI::_bind_methods() { diff --git a/core/input/input_event.h b/core/input/input_event.h index 0eae3a2bbe..6a71a24c8b 100644 --- a/core/input/input_event.h +++ b/core/input/input_event.h @@ -132,7 +132,7 @@ public: virtual bool is_pressed() const; virtual bool is_echo() const; - virtual String as_text() const; + virtual String as_text() const = 0; virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; @@ -207,6 +207,9 @@ public: void set_modifiers_from_event(const InputEventWithModifiers *event); + virtual String as_text() const override; + virtual String to_string() override; + InputEventWithModifiers() {} }; @@ -249,6 +252,7 @@ public: virtual bool is_action_type() const override { return true; } virtual String as_text() const override; + virtual String to_string() override; InputEventKey() {} }; @@ -306,6 +310,7 @@ public: virtual bool is_action_type() const override { return true; } virtual String as_text() const override; + virtual String to_string() override; InputEventMouseButton() {} }; @@ -336,6 +341,7 @@ public: virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; virtual String as_text() const override; + virtual String to_string() override; virtual bool accumulate(const Ref<InputEvent> &p_event) override; @@ -363,6 +369,7 @@ public: virtual bool is_action_type() const override { return true; } virtual String as_text() const override; + virtual String to_string() override; InputEventJoypadMotion() {} }; @@ -391,6 +398,7 @@ public: virtual bool is_action_type() const override { return true; } virtual String as_text() const override; + virtual String to_string() override; InputEventJoypadButton() {} }; @@ -416,6 +424,7 @@ public: virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; virtual String as_text() const override; + virtual String to_string() override; InputEventScreenTouch() {} }; @@ -445,6 +454,7 @@ public: virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; virtual String as_text() const override; + virtual String to_string() override; InputEventScreenDrag() {} }; @@ -476,6 +486,7 @@ public: virtual bool shortcut_match(const Ref<InputEvent> &p_event) const override; virtual bool is_action_type() const override { return true; } virtual String as_text() const override; + virtual String to_string() override; InputEventAction() {} }; @@ -506,6 +517,7 @@ public: virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; virtual String as_text() const override; + virtual String to_string() override; InputEventMagnifyGesture() {} }; @@ -523,6 +535,7 @@ public: virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; virtual String as_text() const override; + virtual String to_string() override; InputEventPanGesture() {} }; @@ -568,6 +581,7 @@ public: int get_controller_value() const; virtual String as_text() const override; + virtual String to_string() override; InputEventMIDI() {} }; diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 7e32f215e7..9883ce12a0 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -168,6 +168,7 @@ void register_core_types() { ClassDB::register_class<AESContext>(); ClassDB::register_custom_instance_class<X509Certificate>(); ClassDB::register_custom_instance_class<CryptoKey>(); + ClassDB::register_custom_instance_class<HMACContext>(); ClassDB::register_custom_instance_class<Crypto>(); ClassDB::register_custom_instance_class<StreamPeerSSL>(); diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp index 07b024ecb4..df29ec7b63 100644 --- a/core/variant/variant_op.cpp +++ b/core/variant/variant_op.cpp @@ -1399,6 +1399,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorSub<Vector2i, Vector2i, Vector2i>>(Variant::OP_SUBTRACT, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorSub<Vector3, Vector3, Vector3>>(Variant::OP_SUBTRACT, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorSub<Vector3i, Vector3i, Vector3i>>(Variant::OP_SUBTRACT, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorSub<Quat, Quat, Quat>>(Variant::OP_SUBTRACT, Variant::QUAT, Variant::QUAT); + register_op<OperatorEvaluatorSub<Color, Color, Color>>(Variant::OP_SUBTRACT, Variant::COLOR, Variant::COLOR); register_op<OperatorEvaluatorMul<int64_t, int64_t, int64_t>>(Variant::OP_MULTIPLY, Variant::INT, Variant::INT); register_op<OperatorEvaluatorMul<double, int64_t, double>>(Variant::OP_MULTIPLY, Variant::INT, Variant::FLOAT); diff --git a/doc/classes/Crypto.xml b/doc/classes/Crypto.xml index b3bbbae94f..1f6cb40cde 100644 --- a/doc/classes/Crypto.xml +++ b/doc/classes/Crypto.xml @@ -73,6 +73,18 @@ <tutorials> </tutorials> <methods> + <method name="constant_time_compare"> + <return type="bool"> + </return> + <argument index="0" name="trusted" type="PackedByteArray"> + </argument> + <argument index="1" name="received" type="PackedByteArray"> + </argument> + <description> + Compares two [PackedByteArray]s for equality without leaking timing information in order to prevent timing attacks. + See [url=https://paragonie.com/blog/2015/11/preventing-timing-attacks-on-string-comparison-with-double-hmac-strategy]this blog post[/url] for more information. + </description> + </method> <method name="decrypt"> <return type="PackedByteArray"> </return> @@ -147,6 +159,20 @@ [/codeblocks] </description> </method> + <method name="hmac_digest"> + <return type="PackedByteArray"> + </return> + <argument index="0" name="hash_type" type="int" enum="HashingContext.HashType"> + </argument> + <argument index="1" name="key" type="PackedByteArray"> + </argument> + <argument index="2" name="msg" type="PackedByteArray"> + </argument> + <description> + Generates an [url=https://en.wikipedia.org/wiki/HMAC]HMAC[/url] digest of [code]msg[/code] using [code]key[/code]. The [code]hash_type[/code] parameter is the hashing algorithm that is used for the inner and outer hashes. + Currently, only [constant HashingContext.HASH_SHA256] and [constant HashingContext.HASH_SHA1] are supported. + </description> + </method> <method name="sign"> <return type="PackedByteArray"> </return> diff --git a/doc/classes/HMACContext.xml b/doc/classes/HMACContext.xml new file mode 100644 index 0000000000..00d528ef8f --- /dev/null +++ b/doc/classes/HMACContext.xml @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="HMACContext" inherits="Reference" version="4.0"> + <brief_description> + Used to create an HMAC for a message using a key. + </brief_description> + <description> + The HMACContext class is useful for advanced HMAC use cases, such as streaming the message as it supports creating the message over time rather than providing it all at once. + [codeblocks] + [gdscript] + extends Node + var ctx = HMACContext.new() + + func _ready(): + var key = "supersecret".to_utf8() + var err = ctx.start(HashingContext.HASH_SHA256, key) + assert(err == OK) + var msg1 = "this is ".to_utf8() + var msg2 = "vewy vewy secret".to_utf8() + err = ctx.update(msg1) + assert(err == OK) + err = ctx.update(msg2) + assert(err == OK) + var hmac = ctx.finish() + print(hmac.hex_encode()) + + [/gdscript] + [csharp] + using Godot; + using System; + using System.Diagnostics; + + public class CryptoNode : Node + { + private HMACContext ctx = new HMACContext(); + public override void _Ready() + { + PackedByteArray key = String("supersecret").to_utf8(); + Error err = ctx.Start(HashingContext.HASH_SHA256, key); + GD.Assert(err == OK); + PackedByteArray msg1 = String("this is ").to_utf8(); + PackedByteArray msg2 = String("vewy vew secret").to_utf8(); + err = ctx.Update(msg1); + GD.Assert(err == OK); + err = ctx.Update(msg2); + GD.Assert(err == OK); + PackedByteArray hmac = ctx.Finish(); + GD.Print(hmac.HexEncode()); + } + } + + [/csharp] + [/codeblocks] + [b]Note:[/b] Not available in HTML5 exports. + </description> + <tutorials> + </tutorials> + <methods> + <method name="finish"> + <return type="PackedByteArray"> + </return> + <description> + Returns the resulting HMAC. If the HMAC failed, an empty [PackedByteArray] is returned. + </description> + </method> + <method name="start"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="hash_type" type="int" enum="HashingContext.HashType"> + </argument> + <argument index="1" name="key" type="PackedByteArray"> + </argument> + <description> + Initializes the HMACContext. This method cannot be called again on the same HMACContext until [method finish] has been called. + </description> + </method> + <method name="update"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="data" type="PackedByteArray"> + </argument> + <description> + Updates the message to be HMACed. This can be called multiple times before [method finish] is called to append [code]data[/code] to the message, but cannot be called until [method start] has been called. + </description> + </method> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/int.xml b/doc/classes/int.xml index b0d0a4bd7b..a63c509937 100644 --- a/doc/classes/int.xml +++ b/doc/classes/int.xml @@ -70,7 +70,7 @@ <argument index="0" name="from" type="float"> </argument> <description> - Cast a float value to an integer value, this method simply removes the number fractions, so for example [code]int(2.7)[/code] will be equals to 2, [code]int(.1)[/code] will be equals to 0 and [code]int(-2.7)[/code] will be equals to -2. + Cast a float value to an integer value, this method simply removes the number fractions (i.e. rounds [code]from[/code] towards zero), so for example [code]int(2.7)[/code] will be equals to 2, [code]int(0.1)[/code] will be equals to 0 and [code]int(-2.7)[/code] will be equals to -2. This operation is also called truncation. </description> </method> <method name="operator !=" qualifiers="operator"> diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 3d5da5f68f..aa19bdf342 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -2368,16 +2368,16 @@ void FileSystemDock::_file_and_folders_fill_popup(PopupMenu *p_popup, Vector<Str } if (p_paths.size() == 1) { - p_popup->add_icon_item(get_theme_icon("ActionCopy", "EditorIcons"), TTR("Copy Path"), FILE_COPY_PATH); + p_popup->add_icon_shortcut(get_theme_icon("ActionCopy", "EditorIcons"), ED_GET_SHORTCUT("filesystem_dock/copy_path"), FILE_COPY_PATH); if (p_paths[0] != "res://") { - p_popup->add_icon_item(get_theme_icon("Rename", "EditorIcons"), TTR("Rename..."), FILE_RENAME); - p_popup->add_icon_item(get_theme_icon("Duplicate", "EditorIcons"), TTR("Duplicate..."), FILE_DUPLICATE); + p_popup->add_icon_shortcut(get_theme_icon("Rename", "EditorIcons"), ED_GET_SHORTCUT("filesystem_dock/rename"), FILE_RENAME); + p_popup->add_icon_shortcut(get_theme_icon("Duplicate", "EditorIcons"), ED_GET_SHORTCUT("filesystem_dock/duplicate"), FILE_DUPLICATE); } } if (p_paths.size() > 1 || p_paths[0] != "res://") { p_popup->add_icon_item(get_theme_icon("MoveUp", "EditorIcons"), TTR("Move To..."), FILE_MOVE); - p_popup->add_icon_item(get_theme_icon("Remove", "EditorIcons"), TTR("Move to Trash"), FILE_REMOVE); + p_popup->add_icon_shortcut(get_theme_icon("Remove", "EditorIcons"), ED_GET_SHORTCUT("filesystem_dock/delete"), FILE_REMOVE); } if (p_paths.size() == 1) { @@ -2690,8 +2690,8 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { // `KEY_MASK_CMD | KEY_C` conflicts with other editor shortcuts. ED_SHORTCUT("filesystem_dock/copy_path", TTR("Copy Path"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_C); ED_SHORTCUT("filesystem_dock/duplicate", TTR("Duplicate..."), KEY_MASK_CMD | KEY_D); - ED_SHORTCUT("filesystem_dock/delete", TTR("Delete"), KEY_DELETE); - ED_SHORTCUT("filesystem_dock/rename", TTR("Rename"), KEY_F2); + ED_SHORTCUT("filesystem_dock/delete", TTR("Move to Trash"), KEY_DELETE); + ED_SHORTCUT("filesystem_dock/rename", TTR("Rename..."), KEY_F2); VBoxContainer *top_vbc = memnew(VBoxContainer); add_child(top_vbc); diff --git a/editor/input_map_editor.cpp b/editor/input_map_editor.cpp index 5b6d850096..686fd4c08b 100644 --- a/editor/input_map_editor.cpp +++ b/editor/input_map_editor.cpp @@ -35,47 +35,6 @@ #include "editor/editor_node.h" #include "editor/editor_scale.h" -static const char *_button_descriptions[JOY_BUTTON_SDL_MAX] = { - TTRC("Bottom Action, Sony Cross, Xbox A, Nintendo B"), - TTRC("Right Action, Sony Circle, Xbox B, Nintendo A"), - TTRC("Left Action, Sony Square, Xbox X, Nintendo Y"), - TTRC("Top Action, Sony Triangle, Xbox Y, Nintendo X"), - TTRC("Back, Sony Select, Xbox Back, Nintendo -"), - TTRC("Guide, Sony PS, Xbox Home"), - TTRC("Start, Nintendo +"), - TTRC("Left Stick, Sony L3, Xbox L/LS"), - TTRC("Right Stick, Sony R3, Xbox R/RS"), - TTRC("Left Shoulder, Sony L1, Xbox LB"), - TTRC("Right Shoulder, Sony R1, Xbox RB"), - TTRC("D-pad Up"), - TTRC("D-pad Down"), - TTRC("D-pad Left"), - TTRC("D-pad Right"), -}; - -static const char *_axis_descriptions[JOY_AXIS_MAX * 2] = { - TTRC("Left Stick Left, Joystick 0 Left"), - TTRC("Left Stick Right, Joystick 0 Right"), - TTRC("Left Stick Up, Joystick 0 Up"), - TTRC("Left Stick Down, Joystick 0 Down"), - TTRC("Right Stick Left, Joystick 1 Left"), - TTRC("Right Stick Right, Joystick 1 Right"), - TTRC("Right Stick Up, Joystick 1 Up"), - TTRC("Right Stick Down, Joystick 1 Down"), - TTRC("Joystick 2 Left"), - TTRC("Left Trigger, L2, LT, Joystick 2 Right"), - TTRC("Joystick 2 Up"), - TTRC("Right Trigger, R2, RT, Joystick 2 Down"), - TTRC("Joystick 3 Left"), - TTRC("Joystick 3 Right"), - TTRC("Joystick 3 Up"), - TTRC("Joystick 3 Down"), - TTRC("Joystick 4 Left"), - TTRC("Joystick 4 Right"), - TTRC("Joystick 4 Up"), - TTRC("Joystick 4 Down"), -}; - void InputMapEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -395,6 +354,42 @@ void InputMapEditor::_show_last_added(const Ref<InputEvent> &p_event, const Stri } } +// Maps to 2*axis if value is neg, or + 1 if value is pos. +static const char *_joy_axis_descriptions[JOY_AXIS_MAX * 2] = { + TTRC("Left Stick Left, Joystick 0 Left"), + TTRC("Left Stick Right, Joystick 0 Right"), + TTRC("Left Stick Up, Joystick 0 Up"), + TTRC("Left Stick Down, Joystick 0 Down"), + TTRC("Right Stick Left, Joystick 1 Left"), + TTRC("Right Stick Right, Joystick 1 Right"), + TTRC("Right Stick Up, Joystick 1 Up"), + TTRC("Right Stick Down, Joystick 1 Down"), + TTRC("Joystick 2 Left"), + TTRC("Left Trigger, Sony L2, Xbox LT, Joystick 2 Right"), + TTRC("Joystick 2 Up"), + TTRC("Right Trigger, Sony R2, Xbox RT, Joystick 2 Down"), + TTRC("Joystick 3 Left"), + TTRC("Joystick 3 Right"), + TTRC("Joystick 3 Up"), + TTRC("Joystick 3 Down"), + TTRC("Joystick 4 Left"), + TTRC("Joystick 4 Right"), + TTRC("Joystick 4 Up"), + TTRC("Joystick 4 Down"), +}; + +// Separate from `InputEvent::as_text()` since the descriptions need to be different for the input map editor. See #43660. +String InputMapEditor::_get_joypad_motion_event_text(const Ref<InputEventJoypadMotion> &p_event) { + ERR_FAIL_COND_V_MSG(p_event.is_null(), String(), "Provided event is not a valid instance of InputEventJoypadMotion"); + + String desc = TTR("Unknown Joypad Axis"); + if (p_event->get_axis() < JOY_AXIS_MAX) { + desc = RTR(_joy_axis_descriptions[2 * p_event->get_axis() + (p_event->get_axis_value() < 0 ? 0 : 1)]); + } + + return vformat("Joypad Axis %s %s (%s)", itos(p_event->get_axis()), p_event->get_axis_value() < 0 ? "-" : "+", desc); +} + void InputMapEditor::_wait_for_key(const Ref<InputEvent> &p_event) { Ref<InputEventKey> k = p_event; @@ -481,9 +476,11 @@ void InputMapEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_event) { device_index_label->set_text(TTR("Joypad Axis Index:")); device_index->clear(); for (int i = 0; i < JOY_AXIS_MAX * 2; i++) { - String desc = TTR("Axis") + " " + itos(i / 2) + " " + ((i & 1) ? "+" : "-") + - " (" + TTR(_axis_descriptions[i]) + ")"; - device_index->add_item(desc); + Ref<InputEventJoypadMotion> jm; + jm.instance(); + jm->set_axis(i / 2); + jm->set_axis_value((i & 1) ? 1 : -1); + device_index->add_item(_get_joypad_motion_event_text(jm)); } device_input->popup_centered(Size2(350, 95) * EDSCALE); @@ -502,11 +499,10 @@ void InputMapEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_event) { device_index_label->set_text(TTR("Joypad Button Index:")); device_index->clear(); for (int i = 0; i < JOY_BUTTON_MAX; i++) { - String desc = TTR("Button") + " " + itos(i); - if (i < JOY_BUTTON_SDL_MAX) { - desc += " (" + TTR(_button_descriptions[i]) + ")"; - } - device_index->add_item(desc); + Ref<InputEventJoypadButton> jb; + jb.instance(); + jb->set_button_index(i); + device_index->add_item(jb->as_text()); } device_input->popup_centered(Size2(350, 95) * EDSCALE); @@ -714,14 +710,7 @@ void InputMapEditor::_update_actions() { Ref<InputEventJoypadButton> jb = event; if (jb.is_valid()) { - const int idx = jb->get_button_index(); - String str = _get_device_string(jb->get_device()) + ", " + - TTR("Button") + " " + itos(idx); - if (idx >= 0 && idx < JOY_BUTTON_SDL_MAX) { - str += String() + " (" + TTR(_button_descriptions[jb->get_button_index()]) + ")"; - } - - action2->set_text(0, str); + action2->set_text(0, jb->as_text()); action2->set_icon(0, input_editor->get_theme_icon("JoyButton", "EditorIcons")); } @@ -754,12 +743,8 @@ void InputMapEditor::_update_actions() { Ref<InputEventJoypadMotion> jm = event; if (jm.is_valid()) { - int ax = jm->get_axis(); - int n = 2 * ax + (jm->get_axis_value() < 0 ? 0 : 1); - String str = _get_device_string(jm->get_device()) + ", " + - TTR("Axis") + " " + itos(ax) + " " + (jm->get_axis_value() < 0 ? "-" : "+") + - " (" + _axis_descriptions[n] + ")"; - action2->set_text(0, str); + device_index->add_item(_get_joypad_motion_event_text(jm)); + action2->set_text(0, jm->as_text()); action2->set_icon(0, input_editor->get_theme_icon("JoyAxis", "EditorIcons")); } action2->set_metadata(0, i); diff --git a/editor/input_map_editor.h b/editor/input_map_editor.h index b9a3ce19d4..b59eb97e1d 100644 --- a/editor/input_map_editor.h +++ b/editor/input_map_editor.h @@ -88,6 +88,8 @@ class InputMapEditor : public Control { void _press_a_key_confirm(); void _show_last_added(const Ref<InputEvent> &p_event, const String &p_name); + String _get_joypad_motion_event_text(const Ref<InputEventJoypadMotion> &p_event); + Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index d0928683fd..2530b4ecfe 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2955,11 +2955,11 @@ void Node3DEditorViewport::_menu_option(int p_option) { int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS); bool current = view_menu->get_popup()->is_item_checked(idx); current = !current; + uint32_t layers = ((1 << 20) - 1) | (1 << (GIZMO_BASE_LAYER + index)) | (1 << GIZMO_GRID_LAYER) | (1 << MISC_TOOL_LAYER); if (current) { - camera->set_cull_mask(((1 << 20) - 1) | (1 << (GIZMO_BASE_LAYER + index)) | (1 << GIZMO_EDIT_LAYER) | (1 << GIZMO_GRID_LAYER)); - } else { - camera->set_cull_mask(((1 << 20) - 1) | (1 << (GIZMO_BASE_LAYER + index)) | (1 << GIZMO_GRID_LAYER)); + layers |= (1 << GIZMO_EDIT_LAYER); } + camera->set_cull_mask(layers); view_menu->get_popup()->set_item_checked(idx, current); } break; @@ -3880,7 +3880,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito surface->set_clip_contents(true); camera = memnew(Camera3D); camera->set_disable_gizmo(true); - camera->set_cull_mask(((1 << 20) - 1) | (1 << (GIZMO_BASE_LAYER + p_index)) | (1 << GIZMO_EDIT_LAYER) | (1 << GIZMO_GRID_LAYER)); + camera->set_cull_mask(((1 << 20) - 1) | (1 << (GIZMO_BASE_LAYER + p_index)) | (1 << GIZMO_EDIT_LAYER) | (1 << GIZMO_GRID_LAYER) | (1 << MISC_TOOL_LAYER)); viewport->add_child(camera); camera->make_current(); surface->set_focus_mode(FOCUS_ALL); @@ -4499,12 +4499,14 @@ Object *Node3DEditor::_get_editor_data(Object *p_what) { RS::get_singleton()->instance_geometry_set_cast_shadows_setting( si->sbox_instance, RS::SHADOW_CASTING_SETTING_OFF); + RS::get_singleton()->instance_set_layer_mask(si->sbox_instance, 1 << Node3DEditorViewport::MISC_TOOL_LAYER); si->sbox_instance_xray = RenderingServer::get_singleton()->instance_create2( selection_box_xray->get_rid(), sp->get_world_3d()->get_scenario()); RS::get_singleton()->instance_geometry_set_cast_shadows_setting( si->sbox_instance_xray, RS::SHADOW_CASTING_SETTING_OFF); + RS::get_singleton()->instance_set_layer_mask(si->sbox_instance_xray, 1 << Node3DEditorViewport::MISC_TOOL_LAYER); return si; } diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 2e98fcad4c..12080ea1f0 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -229,6 +229,7 @@ public: GIZMO_BASE_LAYER = 27, GIZMO_EDIT_LAYER = 26, GIZMO_GRID_LAYER = 25, + MISC_TOOL_LAYER = 24, FRAME_TIME_HISTORY = 20, }; diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index eb599df74c..0c64c3640f 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -744,7 +744,7 @@ void RigidBodyBullet::set_continuous_collision_detection(bool p_enable) { } btBody->setCcdSweptSphereRadius(radius * 0.2); } else { - btBody->setCcdMotionThreshold(10000.0); + btBody->setCcdMotionThreshold(0.); btBody->setCcdSweptSphereRadius(0.); } } @@ -824,7 +824,7 @@ void RigidBodyBullet::reload_shapes() { btBody->updateInertiaTensor(); reload_kinematic_shapes(); - set_continuous_collision_detection(btBody->getCcdMotionThreshold() < 9998.0); + set_continuous_collision_detection(is_continuous_collision_detection_enabled()); reload_body(); } diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index d90b3e52d0..eeb66ebfc0 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -55,8 +55,7 @@ <description> Returns the absolute value of parameter [code]s[/code] (i.e. positive value). [codeblock] - # a is 1 - a = abs(-1) + a = abs(-1) # a is 1 [/codeblock] </description> </method> @@ -166,10 +165,10 @@ <description> Rounds [code]s[/code] upward (towards positive infinity), returning the smallest whole number that is not less than [code]s[/code]. [codeblock] - i = ceil(1.45) # i is 2 - i = ceil(1.001) # i is 2 + a = ceil(1.45) # a is 2.0 + a = ceil(1.001) # a is 2.0 [/codeblock] - See also [method floor], [method round], and [method stepify]. + See also [method floor], [method round], [method stepify], and [int]. </description> </method> <method name="char"> @@ -199,13 +198,9 @@ <description> Clamps [code]value[/code] and returns a value not less than [code]min[/code] and not more than [code]max[/code]. [codeblock] - speed = 1000 - # a is 20 - a = clamp(speed, 1, 20) - - speed = -10 - # a is 1 - a = clamp(speed, 1, 20) + a = clamp(1000, 1, 20) # a is 20 + a = clamp(-10, 1, 20) # a is 1 + a = clamp(15, 1, 20) # a is 15 [/codeblock] </description> </method> @@ -236,9 +231,8 @@ <description> Returns the cosine of angle [code]s[/code] in radians. [codeblock] - # Prints 1 then -1 - print(cos(PI * 2)) - print(cos(PI)) + a = cos(TAU) # a is 1.0 + a = cos(PI) # a is -1.0 [/codeblock] </description> </method> @@ -250,8 +244,7 @@ <description> Returns the hyperbolic cosine of [code]s[/code] in radians. [codeblock] - # Prints 1.543081 - print(cosh(1)) + print(cosh(1)) # Prints 1.543081 [/codeblock] </description> </method> @@ -276,8 +269,7 @@ <description> Returns the result of [code]value[/code] decreased by [code]step[/code] * [code]amount[/code]. [codeblock] - # a = 59 - a = dectime(60, 10, 0.1)) + a = dectime(60, 10, 0.1)) # a is 59.0 [/codeblock] </description> </method> @@ -289,8 +281,7 @@ <description> Converts an angle expressed in degrees to radians. [codeblock] - # r is 3.141593 - r = deg2rad(180) + r = deg2rad(180) # r is 3.141593 [/codeblock] </description> </method> @@ -300,7 +291,7 @@ <argument index="0" name="dict" type="Dictionary"> </argument> <description> - Converts a previously converted instance to a dictionary, back into an instance. Useful for deserializing. + Converts a dictionary (previously created with [method inst2dict]) back to an instance. Useful for deserializing. </description> </method> <method name="ease"> @@ -336,13 +327,12 @@ <description> Rounds [code]s[/code] downward (towards negative infinity), returning the largest whole number that is not more than [code]s[/code]. [codeblock] - # a is 2.0 - a = floor(2.99) - # a is -3.0 - a = floor(-2.99) + a = floor(2.45) # a is 2.0 + a = floor(2.99) # a is 2.0 + a = floor(-2.99) # a is -3.0 [/codeblock] - See also [method ceil], [method round], and [method stepify]. - [b]Note:[/b] This method returns a float. If you need an integer, you can use [code]int(s)[/code] directly. + See also [method ceil], [method round], [method stepify], and [int]. + [b]Note:[/b] This method returns a float. If you need an integer and [code]s[/code] is a non-negative number, you can use [code]int(s)[/code] directly. </description> </method> <method name="fmod"> @@ -355,8 +345,7 @@ <description> Returns the floating-point remainder of [code]a/b[/code], keeping the sign of [code]a[/code]. [codeblock] - # Remainder is 1.5 - var remainder = fmod(7, 5.5) + r = fmod(7, 5.5) # r is 1.5 [/codeblock] For the integer remainder operation, use the % operator. </description> @@ -776,7 +765,7 @@ <description> Returns the result of [code]x[/code] raised to the power of [code]y[/code]. [codeblock] - pow(2, 5) # Returns 32 + pow(2, 5) # Returns 32.0 [/codeblock] </description> </method> @@ -801,7 +790,7 @@ Converts one or more arguments to strings in the best way possible and prints them to the console. [codeblock] a = [1, 2, 3] - print("a", "b", a) # Prints ab[1, 2, 3] + print("a", "=", a) # Prints a=[1, 2, 3] [/codeblock] [b]Note:[/b] Consider using [method push_error] and [method push_warning] to print error and warning messages instead of [method print]. This distinguishes them from print messages used for debugging purposes, while also displaying a stack trace when an error or warning is printed. </description> @@ -900,7 +889,7 @@ <description> Converts an angle expressed in radians to degrees. [codeblock] - rad2deg(0.523599) # Returns 30 + rad2deg(0.523599) # Returns 30.0 [/codeblock] </description> </method> @@ -1022,9 +1011,11 @@ <description> Rounds [code]s[/code] to the nearest whole number, with halfway cases rounded away from zero. [codeblock] - round(2.6) # Returns 3 + a = round(2.49) # a is 2.0 + a = round(2.5) # a is 3.0 + a = round(2.51) # a is 3.0 [/codeblock] - See also [method floor], [method ceil], and [method stepify]. + See also [method floor], [method ceil], [method stepify], and [int]. </description> </method> <method name="seed"> @@ -1094,9 +1085,9 @@ This S-shaped curve is the cubic Hermite interpolator, given by [code]f(s) = 3*s^2 - 2*s^3[/code]. [codeblock] smoothstep(0, 2, -5.0) # Returns 0.0 - smoothstep(0, 2, 0.5) # Returns 0.15625 - smoothstep(0, 2, 1.0) # Returns 0.5 - smoothstep(0, 2, 2.0) # Returns 1.0 + smoothstep(0, 2, 0.5) # Returns 0.15625 + smoothstep(0, 2, 1.0) # Returns 0.5 + smoothstep(0, 2, 2.0) # Returns 1.0 [/codeblock] </description> </method> @@ -1121,12 +1112,9 @@ <description> Returns the position of the first non-zero digit, after the decimal point. Note that the maximum return value is 10, which is a design decision in the implementation. [codeblock] - # n is 0 - n = step_decimals(5) - # n is 4 - n = step_decimals(1.0005) - # n is 9 - n = step_decimals(0.000000005) + n = step_decimals(5) # n is 0 + n = step_decimals(1.0005) # n is 4 + n = step_decimals(0.000000005) # n is 9 [/codeblock] </description> </method> @@ -1140,10 +1128,10 @@ <description> Snaps float value [code]s[/code] to a given [code]step[/code]. This can also be used to round a floating point number to an arbitrary number of decimals. [codeblock] - stepify(100, 32) # Returns 96 + stepify(100, 32) # Returns 96.0 stepify(3.14159, 0.01) # Returns 3.14 [/codeblock] - See also [method ceil], [method floor], and [method round]. + See also [method ceil], [method floor], [method round], and [int]. </description> </method> <method name="str" qualifiers="vararg"> @@ -1193,8 +1181,8 @@ <description> Returns the hyperbolic tangent of [code]s[/code]. [codeblock] - a = log(2.0) # Returns 0.693147 - tanh(a) # Returns 0.6 + a = log(2.0) # a is 0.693147 + b = tanh(a) # b is 0.6 [/codeblock] </description> </method> diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 5a6240f31a..1b76c7f967 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -1616,7 +1616,7 @@ void GDScriptAnalyzer::reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_o if (p_binary_op->reduced_value.get_type() == Variant::STRING) { push_error(vformat(R"(%s in operator %s.)", p_binary_op->reduced_value, Variant::get_operator_name(p_binary_op->variant_op)), p_binary_op); } else { - push_error(vformat(R"(Invalid operands to operator %s, %s and %s.".)", + push_error(vformat(R"(Invalid operands to operator %s, %s and %s.)", Variant::get_operator_name(p_binary_op->variant_op), Variant::get_type_name(p_binary_op->left_operand->reduced_value.get_type()), Variant::get_type_name(p_binary_op->right_operand->reduced_value.get_type())), diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 0e6ec7f520..cda217acf0 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -1030,11 +1030,15 @@ void GridMapEditor::_notification(int p_what) { for (int i = 0; i < 3; i++) { grid[i] = RS::get_singleton()->mesh_create(); grid_instance[i] = RS::get_singleton()->instance_create2(grid[i], get_tree()->get_root()->get_world_3d()->get_scenario()); + RenderingServer::get_singleton()->instance_set_layer_mask(grid_instance[i], 1 << Node3DEditorViewport::MISC_TOOL_LAYER); selection_level_instance[i] = RenderingServer::get_singleton()->instance_create2(selection_level_mesh[i], get_tree()->get_root()->get_world_3d()->get_scenario()); + RenderingServer::get_singleton()->instance_set_layer_mask(selection_level_instance[i], 1 << Node3DEditorViewport::MISC_TOOL_LAYER); } selection_instance = RenderingServer::get_singleton()->instance_create2(selection_mesh, get_tree()->get_root()->get_world_3d()->get_scenario()); + RenderingServer::get_singleton()->instance_set_layer_mask(selection_instance, 1 << Node3DEditorViewport::MISC_TOOL_LAYER); paste_instance = RenderingServer::get_singleton()->instance_create2(paste_mesh, get_tree()->get_root()->get_world_3d()->get_scenario()); + RenderingServer::get_singleton()->instance_set_layer_mask(paste_instance, 1 << Node3DEditorViewport::MISC_TOOL_LAYER); _update_selection_transform(); _update_paste_indicator(); diff --git a/modules/mbedtls/SCsub b/modules/mbedtls/SCsub index 5f5d25a3ee..3b1739c6ee 100755 --- a/modules/mbedtls/SCsub +++ b/modules/mbedtls/SCsub @@ -100,3 +100,7 @@ if env["builtin_mbedtls"]: # Module sources env_mbed_tls.add_source_files(env.modules_sources, "*.cpp") + +if env["tests"]: + env_mbed_tls.Append(CPPDEFINES=["TESTS_ENABLED"]) + env_mbed_tls.add_source_files(env.modules_sources, "./tests/*.cpp") diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp index bec792450a..4ea38ebd60 100644 --- a/modules/mbedtls/crypto_mbedtls.cpp +++ b/modules/mbedtls/crypto_mbedtls.cpp @@ -44,6 +44,7 @@ #define PEM_END_CRT "-----END CERTIFICATE-----\n" #include <mbedtls/debug.h> +#include <mbedtls/md.h> #include <mbedtls/pem.h> CryptoKey *CryptoKeyMbedTLS::create() { @@ -186,6 +187,68 @@ Error X509CertificateMbedTLS::save(String p_path) { return OK; } +bool HMACContextMbedTLS::is_md_type_allowed(mbedtls_md_type_t p_md_type) { + switch (p_md_type) { + case MBEDTLS_MD_SHA1: + case MBEDTLS_MD_SHA256: + return true; + default: + return false; + } +} + +HMACContext *HMACContextMbedTLS::create() { + return memnew(HMACContextMbedTLS); +} + +Error HMACContextMbedTLS::start(HashingContext::HashType p_hash_type, PackedByteArray p_key) { + ERR_FAIL_COND_V_MSG(ctx != nullptr, ERR_FILE_ALREADY_IN_USE, "HMACContext already started."); + + // HMAC keys can be any size. + ERR_FAIL_COND_V_MSG(p_key.empty(), ERR_INVALID_PARAMETER, "Key must not be empty."); + + hash_type = p_hash_type; + mbedtls_md_type_t ht = CryptoMbedTLS::md_type_from_hashtype(p_hash_type, hash_len); + + bool allowed = HMACContextMbedTLS::is_md_type_allowed(ht); + ERR_FAIL_COND_V_MSG(!allowed, ERR_INVALID_PARAMETER, "Unsupported hash type."); + + ctx = memalloc(sizeof(mbedtls_md_context_t)); + mbedtls_md_init((mbedtls_md_context_t *)ctx); + + mbedtls_md_setup((mbedtls_md_context_t *)ctx, mbedtls_md_info_from_type((mbedtls_md_type_t)ht), 1); + int ret = mbedtls_md_hmac_starts((mbedtls_md_context_t *)ctx, (const uint8_t *)p_key.ptr(), (size_t)p_key.size()); + return ret ? FAILED : OK; +} + +Error HMACContextMbedTLS::update(PackedByteArray p_data) { + ERR_FAIL_COND_V_MSG(ctx == nullptr, ERR_INVALID_DATA, "Start must be called before update."); + + ERR_FAIL_COND_V_MSG(p_data.empty(), ERR_INVALID_PARAMETER, "Src must not be empty."); + + int ret = mbedtls_md_hmac_update((mbedtls_md_context_t *)ctx, (const uint8_t *)p_data.ptr(), (size_t)p_data.size()); + return ret ? FAILED : OK; +} + +PackedByteArray HMACContextMbedTLS::finish() { + ERR_FAIL_COND_V_MSG(ctx == nullptr, PackedByteArray(), "Start must be called before finish."); + ERR_FAIL_COND_V_MSG(hash_len == 0, PackedByteArray(), "Unsupported hash type."); + + PackedByteArray out; + out.resize(hash_len); + + unsigned char *out_ptr = (unsigned char *)out.ptrw(); + int ret = mbedtls_md_hmac_finish((mbedtls_md_context_t *)ctx, out_ptr); + + mbedtls_md_free((mbedtls_md_context_t *)ctx); + memfree((mbedtls_md_context_t *)ctx); + ctx = nullptr; + hash_len = 0; + + ERR_FAIL_COND_V_MSG(ret, PackedByteArray(), "Error received while finishing HMAC"); + return out; +} + Crypto *CryptoMbedTLS::create() { return memnew(CryptoMbedTLS); } @@ -199,6 +262,7 @@ void CryptoMbedTLS::initialize_crypto() { Crypto::_load_default_certificates = load_default_certificates; X509CertificateMbedTLS::make_default(); CryptoKeyMbedTLS::make_default(); + HMACContextMbedTLS::make_default(); } void CryptoMbedTLS::finalize_crypto() { @@ -210,6 +274,7 @@ void CryptoMbedTLS::finalize_crypto() { } X509CertificateMbedTLS::finalize(); CryptoKeyMbedTLS::finalize(); + HMACContextMbedTLS::finalize(); } CryptoMbedTLS::CryptoMbedTLS() { @@ -313,7 +378,7 @@ PackedByteArray CryptoMbedTLS::generate_random_bytes(int p_bytes) { return out; } -mbedtls_md_type_t CryptoMbedTLS::_md_type_from_hashtype(HashingContext::HashType p_hash_type, int &r_size) { +mbedtls_md_type_t CryptoMbedTLS::md_type_from_hashtype(HashingContext::HashType p_hash_type, int &r_size) { switch (p_hash_type) { case HashingContext::HASH_MD5: r_size = 16; @@ -332,7 +397,7 @@ mbedtls_md_type_t CryptoMbedTLS::_md_type_from_hashtype(HashingContext::HashType Vector<uint8_t> CryptoMbedTLS::sign(HashingContext::HashType p_hash_type, Vector<uint8_t> p_hash, Ref<CryptoKey> p_key) { int size; - mbedtls_md_type_t type = _md_type_from_hashtype(p_hash_type, size); + mbedtls_md_type_t type = CryptoMbedTLS::md_type_from_hashtype(p_hash_type, size); ERR_FAIL_COND_V_MSG(type == MBEDTLS_MD_NONE, Vector<uint8_t>(), "Invalid hash type."); ERR_FAIL_COND_V_MSG(p_hash.size() != size, Vector<uint8_t>(), "Invalid hash provided. Size must be " + itos(size)); Ref<CryptoKeyMbedTLS> key = static_cast<Ref<CryptoKeyMbedTLS>>(p_key); @@ -350,7 +415,7 @@ Vector<uint8_t> CryptoMbedTLS::sign(HashingContext::HashType p_hash_type, Vector bool CryptoMbedTLS::verify(HashingContext::HashType p_hash_type, Vector<uint8_t> p_hash, Vector<uint8_t> p_signature, Ref<CryptoKey> p_key) { int size; - mbedtls_md_type_t type = _md_type_from_hashtype(p_hash_type, size); + mbedtls_md_type_t type = CryptoMbedTLS::md_type_from_hashtype(p_hash_type, size); ERR_FAIL_COND_V_MSG(type == MBEDTLS_MD_NONE, false, "Invalid hash type."); ERR_FAIL_COND_V_MSG(p_hash.size() != size, false, "Invalid hash provided. Size must be " + itos(size)); Ref<CryptoKeyMbedTLS> key = static_cast<Ref<CryptoKeyMbedTLS>>(p_key); diff --git a/modules/mbedtls/crypto_mbedtls.h b/modules/mbedtls/crypto_mbedtls.h index e40ca08643..990f8ae578 100644 --- a/modules/mbedtls/crypto_mbedtls.h +++ b/modules/mbedtls/crypto_mbedtls.h @@ -101,12 +101,31 @@ public: friend class SSLContextMbedTLS; }; +class HMACContextMbedTLS : public HMACContext { +private: + HashingContext::HashType hash_type; + int hash_len = 0; + void *ctx = nullptr; + +public: + static HMACContext *create(); + static void make_default() { HMACContext::_create = create; } + static void finalize() { HMACContext::_create = nullptr; } + + static bool is_md_type_allowed(mbedtls_md_type_t p_md_type); + + virtual Error start(HashingContext::HashType p_hash_type, PackedByteArray p_key); + virtual Error update(PackedByteArray p_data); + virtual PackedByteArray finish(); + + HMACContextMbedTLS() {} +}; + class CryptoMbedTLS : public Crypto { private: mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; static X509CertificateMbedTLS *default_certs; - mbedtls_md_type_t _md_type_from_hashtype(HashingContext::HashType p_hash_type, int &r_size); public: static Crypto *create(); @@ -114,6 +133,7 @@ public: static void finalize_crypto(); static X509CertificateMbedTLS *get_default_certificates(); static void load_default_certificates(String p_path); + static mbedtls_md_type_t md_type_from_hashtype(HashingContext::HashType p_hash_type, int &r_size); virtual PackedByteArray generate_random_bytes(int p_bytes); virtual Ref<CryptoKey> generate_rsa(int p_bytes); diff --git a/modules/mbedtls/register_types.cpp b/modules/mbedtls/register_types.cpp index 84a27c29bd..59abbac8ec 100644 --- a/modules/mbedtls/register_types.cpp +++ b/modules/mbedtls/register_types.cpp @@ -35,6 +35,10 @@ #include "packet_peer_mbed_dtls.h" #include "stream_peer_mbedtls.h" +#ifdef TESTS_ENABLED +#include "tests/test_crypto_mbedtls.h" +#endif + void register_mbedtls_types() { CryptoMbedTLS::initialize_crypto(); StreamPeerMbedTLS::initialize_ssl(); diff --git a/modules/mbedtls/tests/test_crypto_mbedtls.cpp b/modules/mbedtls/tests/test_crypto_mbedtls.cpp new file mode 100644 index 0000000000..c5a27aa794 --- /dev/null +++ b/modules/mbedtls/tests/test_crypto_mbedtls.cpp @@ -0,0 +1,62 @@ +/*************************************************************************/ +/* test_crypto_mbedtls.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* 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.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "modules/mbedtls/tests/test_crypto_mbedtls.h" + +#include "modules/mbedtls/crypto_mbedtls.h" +#include "tests/test_macros.h" + +namespace TestCryptoMbedTLS { + +void hmac_digest_test(HashingContext::HashType ht, String expected_hex) { + CryptoMbedTLS crypto; + PackedByteArray key = String("supersecretkey").to_utf8_buffer(); + PackedByteArray msg = String("Return of the MAC!").to_utf8_buffer(); + PackedByteArray digest = crypto.hmac_digest(ht, key, msg); + String hex = String::hex_encode_buffer(digest.ptr(), digest.size()); + CHECK(hex == expected_hex); +} + +void hmac_context_digest_test(HashingContext::HashType ht, String expected_hex) { + HMACContextMbedTLS ctx; + PackedByteArray key = String("supersecretkey").to_utf8_buffer(); + PackedByteArray msg1 = String("Return of ").to_utf8_buffer(); + PackedByteArray msg2 = String("the MAC!").to_utf8_buffer(); + Error err = ctx.start(ht, key); + CHECK(err == OK); + err = ctx.update(msg1); + CHECK(err == OK); + err = ctx.update(msg2); + CHECK(err == OK); + PackedByteArray digest = ctx.finish(); + String hex = String::hex_encode_buffer(digest.ptr(), digest.size()); + CHECK(hex == expected_hex); +} +} // namespace TestCryptoMbedTLS diff --git a/modules/mbedtls/tests/test_crypto_mbedtls.h b/modules/mbedtls/tests/test_crypto_mbedtls.h new file mode 100644 index 0000000000..7b1e062239 --- /dev/null +++ b/modules/mbedtls/tests/test_crypto_mbedtls.h @@ -0,0 +1,61 @@ +/*************************************************************************/ +/* test_crypto_mbedtls.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* 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.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_CRYPTO_MBEDTLS_H +#define TEST_CRYPTO_MBEDTLS_H + +#include "core/crypto/hashing_context.h" + +#include "tests/test_macros.h" + +namespace TestCryptoMbedTLS { + +void hmac_digest_test(HashingContext::HashType ht, String expected_hex); + +TEST_CASE("[CryptoMbedTLS] HMAC digest") { + // SHA-256 + hmac_digest_test(HashingContext::HashType::HASH_SHA256, "fe442023f8a7d36a810e1e7cd8a8e2816457f350a008fbf638296afa12085e59"); + + // SHA-1 + hmac_digest_test(HashingContext::HashType::HASH_SHA1, "a0ac4cd68a2f4812c355983d94e8d025afe7dddf"); +} + +void hmac_context_digest_test(HashingContext::HashType ht, String expected_hex); + +TEST_CASE("[HMACContext] HMAC digest") { + // SHA-256 + hmac_context_digest_test(HashingContext::HashType::HASH_SHA256, "fe442023f8a7d36a810e1e7cd8a8e2816457f350a008fbf638296afa12085e59"); + + // SHA-1 + hmac_context_digest_test(HashingContext::HashType::HASH_SHA1, "a0ac4cd68a2f4812c355983d94e8d025afe7dddf"); +} +} // namespace TestCryptoMbedTLS + +#endif // TEST_CRYPTO_MBEDTLS_H diff --git a/modules/mono/build_scripts/make_android_mono_config.py b/modules/mono/build_scripts/make_android_mono_config.py index 04f8c80243..28494bff6e 100644 --- a/modules/mono/build_scripts/make_android_mono_config.py +++ b/modules/mono/build_scripts/make_android_mono_config.py @@ -38,10 +38,10 @@ String get_godot_android_mono_config() { Vector<uint8_t> data; data.resize(config_uncompressed_size); uint8_t* w = data.ptrw(); - Compression::decompress(w.ptr(), config_uncompressed_size, config_compressed_data, + Compression::decompress(w, config_uncompressed_size, config_compressed_data, config_compressed_size, Compression::MODE_DEFLATE); String s; - if (s.parse_utf8((const char *)w.ptr(), data.size())) { + if (s.parse_utf8((const char *)w, data.size())) { ERR_FAIL_V(String()); } return s; diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java index f3e985f944..6d5be312f1 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java @@ -181,6 +181,7 @@ public class GodotInputHandler implements InputDeviceListener { arr[i * 3 + 2] = event.getY(i); } final int action = event.getActionMasked(); + final int pointer_idx = event.getPointerId(event.getActionIndex()); mRenderView.queueOnRenderThread(new Runnable() { @Override @@ -189,12 +190,9 @@ public class GodotInputHandler implements InputDeviceListener { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_MOVE: { - GodotLib.touch(event.getSource(), action, 0, evcount, arr); - } break; + case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_POINTER_DOWN: { - int pointer_idx = event.getPointerId(event.getActionIndex()); GodotLib.touch(event.getSource(), action, pointer_idx, evcount, arr); } break; } diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index e988e51e72..1dfe614b49 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -42,7 +42,7 @@ #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "platform/osx/logo.gen.h" -#include "string.h" + #include <sys/stat.h> class EditorExportPlatformOSX : public EditorExportPlatform { @@ -572,36 +572,36 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p pkg_name = "Unnamed"; } - String pkg_name_safe = OS::get_singleton()->get_safe_dir_name(pkg_name); - - Error err = OK; - String tmp_app_path_name = ""; + pkg_name = OS::get_singleton()->get_safe_dir_name(pkg_name); - DirAccess *tmp_app_path = nullptr; String export_format = use_dmg() && p_path.ends_with("dmg") ? "dmg" : "zip"; // Create our application bundle. - tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".app"); + String tmp_app_dir_name = pkg_name; + String tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(tmp_app_dir_name); print_line("Exporting to " + tmp_app_path_name); - tmp_app_path = DirAccess::create_for_path(tmp_app_path_name); - if (!tmp_app_path) { + + Error err = OK; + + DirAccessRef tmp_app_dir = DirAccess::create_for_path(tmp_app_path_name); + if (!tmp_app_dir) { err = ERR_CANT_CREATE; } // Create our folder structure. if (err == OK) { print_line("Creating " + tmp_app_path_name + "/Contents/MacOS"); - err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/MacOS"); + err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/MacOS"); } if (err == OK) { print_line("Creating " + tmp_app_path_name + "/Contents/Frameworks"); - err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks"); + err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks"); } if (err == OK) { print_line("Creating " + tmp_app_path_name + "/Contents/Resources"); - err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Resources"); + err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/Resources"); } // Now process our template. @@ -678,14 +678,14 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p ret = unzGoToNextFile(src_pkg_zip); continue; // skip } - file = file.replace("/data.mono.osx.64.release_debug/", "/data_" + pkg_name_safe + "/"); + file = file.replace("/data.mono.osx.64.release_debug/", "/data_" + pkg_name + "/"); } if (file.find("/data.mono.osx.64.release/") != -1) { if (p_debug) { ret = unzGoToNextFile(src_pkg_zip); continue; // skip } - file = file.replace("/data.mono.osx.64.release/", "/data_" + pkg_name_safe + "/"); + file = file.replace("/data.mono.osx.64.release/", "/data_" + pkg_name + "/"); } print_line("ADDING: " + file + " size: " + itos(data.size())); @@ -694,7 +694,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p // Write it into our application bundle. file = tmp_app_path_name.plus_file(file); if (err == OK) { - err = tmp_app_path->make_dir_recursive(file.get_base_dir()); + err = tmp_app_dir->make_dir_recursive(file.get_base_dir()); } if (err == OK) { FileAccess *f = FileAccess::open(file, FileAccess::WRITE); @@ -797,7 +797,10 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p } // Clean up temporary .app dir. - OS::get_singleton()->move_to_trash(tmp_app_path_name); + tmp_app_dir->change_dir(tmp_app_path_name); + tmp_app_dir->erase_contents_recursive(); + tmp_app_dir->change_dir(".."); + tmp_app_dir->remove(tmp_app_dir_name); } return err; diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index 62ccd55e89..3a54ac7443 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -431,6 +431,7 @@ void ScrollContainer::update_scrollbars() { v_scroll->set_max(min.height); if (hide_scroll_v) { + v_scroll->set_page(size.height); v_scroll->hide(); scroll.y = 0; } else { @@ -446,6 +447,7 @@ void ScrollContainer::update_scrollbars() { h_scroll->set_max(min.width); if (hide_scroll_h) { + h_scroll->set_page(size.width); h_scroll->hide(); scroll.x = 0; } else { diff --git a/tests/test_crypto.h b/tests/test_crypto.h new file mode 100644 index 0000000000..9e219ceec9 --- /dev/null +++ b/tests/test_crypto.h @@ -0,0 +1,74 @@ +/*************************************************************************/ +/* test_crypto.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* 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.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_CRYPTO_H +#define TEST_CRYPTO_H + +#include "core/crypto/crypto.h" +#include "tests/test_macros.h" +#include <stdio.h> + +namespace TestCrypto { + +class _MockCrypto : public Crypto { + virtual PackedByteArray generate_random_bytes(int p_bytes) { return PackedByteArray(); } + virtual Ref<CryptoKey> generate_rsa(int p_bytes) { return nullptr; } + virtual Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after) { return nullptr; } + + virtual Vector<uint8_t> sign(HashingContext::HashType p_hash_type, Vector<uint8_t> p_hash, Ref<CryptoKey> p_key) { return Vector<uint8_t>(); } + virtual bool verify(HashingContext::HashType p_hash_type, Vector<uint8_t> p_hash, Vector<uint8_t> p_signature, Ref<CryptoKey> p_key) { return false; } + virtual Vector<uint8_t> encrypt(Ref<CryptoKey> p_key, Vector<uint8_t> p_plaintext) { return Vector<uint8_t>(); } + virtual Vector<uint8_t> decrypt(Ref<CryptoKey> p_key, Vector<uint8_t> p_ciphertext) { return Vector<uint8_t>(); } + virtual PackedByteArray hmac_digest(HashingContext::HashType p_hash_type, PackedByteArray p_key, PackedByteArray p_msg) { return PackedByteArray(); } +}; + +PackedByteArray raw_to_pba(const uint8_t *arr, size_t len) { + PackedByteArray pba; + pba.resize(len); + for (size_t i = 0; i < len; i++) { + pba.set(i, arr[i]); + } + return pba; +} + +TEST_CASE("[Crypto] PackedByteArray constant time compare") { + const uint8_t hm1[] = { 144, 140, 176, 38, 88, 113, 101, 45, 71, 105, 10, 91, 248, 16, 117, 244, 189, 30, 238, 29, 219, 134, 82, 130, 212, 114, 161, 166, 188, 169, 200, 106 }; + const uint8_t hm2[] = { 80, 30, 144, 228, 108, 38, 188, 125, 150, 64, 165, 127, 221, 118, 144, 232, 45, 100, 15, 248, 193, 244, 245, 34, 116, 147, 132, 200, 110, 27, 38, 75 }; + PackedByteArray p1 = raw_to_pba(hm1, sizeof(hm1) / sizeof(hm1[0])); + PackedByteArray p2 = raw_to_pba(hm2, sizeof(hm2) / sizeof(hm2[0])); + _MockCrypto crypto; + bool equal = crypto.constant_time_compare(p1, p1); + CHECK(equal); + equal = crypto.constant_time_compare(p1, p2); + CHECK(!equal); +} +} // namespace TestCrypto + +#endif // TEST_CRYPTO_H diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 9d1e7da6f7..dd8c36e737 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -39,6 +39,7 @@ #include "test_color.h" #include "test_command_queue.h" #include "test_config_file.h" +#include "test_crypto.h" #include "test_curve.h" #include "test_expression.h" #include "test_gradient.h" |