diff --git a/.gitignore b/.gitignore index 4502c6e..b9c4362 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,10 @@ -## JetBrains IDEs -/.idea/ -*.iml - -## Maven -/**/target/ -/dependency-reduced-pom.xml - -## Misc. -.DS_Store +## JetBrains IDEs +/.idea/ +*.iml + +## Maven +/**/target/ +/dependency-reduced-pom.xml + +## Misc. +.DS_Store diff --git a/LICENSE b/LICENSE index c4bdc05..6328600 100644 --- a/LICENSE +++ b/LICENSE @@ -1,327 +1,327 @@ -Creative Commons Attribution-NonCommercial-NoDerivatives 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-NonCommercial-NoDerivatives 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. 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. - - c. 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. - - d. 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. - - e. Licensed Material means the artistic or literary work, database, - or other material to which the Licensor applied this Public - License. - - f. 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. - - g. Licensor means the individual(s) or entity(ies) granting rights - under this Public License. - - h. NonCommercial means not primarily intended for or directed towards - commercial advantage or monetary compensation. For purposes of - this Public License, the exchange of the Licensed Material for - other material subject to Copyright and Similar Rights by digital - file-sharing or similar means is NonCommercial provided there is - no payment of monetary compensation in connection with the - exchange. - - 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, for NonCommercial purposes only; and - - b. produce and reproduce, but not Share, Adapted Material - for NonCommercial purposes only. - - 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, including when - the Licensed Material is used other than for NonCommercial - purposes. - - -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, 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. - - For the avoidance of doubt, You do not have permission under - this Public License to Share Adapted Material. - - 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. - - -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 for NonCommercial purposes - only and provided You do not Share Adapted Material; - - 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. - - 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. - - 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. - - -Section 6 -- Term and Termination. - - 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. - - b. Where Your right to use the Licensed Material has terminated under - Section 6(a), it reinstates: - - 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. - -======================================================================= +Creative Commons Attribution-NonCommercial-NoDerivatives 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-NonCommercial-NoDerivatives 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. 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. + + c. 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. + + d. 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. + + e. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + f. 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. + + g. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + h. NonCommercial means not primarily intended for or directed towards + commercial advantage or monetary compensation. For purposes of + this Public License, the exchange of the Licensed Material for + other material subject to Copyright and Similar Rights by digital + file-sharing or similar means is NonCommercial provided there is + no payment of monetary compensation in connection with the + exchange. + + 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, for NonCommercial purposes only; and + + b. produce and reproduce, but not Share, Adapted Material + for NonCommercial purposes only. + + 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, including when + the Licensed Material is used other than for NonCommercial + purposes. + + +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, 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. + + For the avoidance of doubt, You do not have permission under + this Public License to Share Adapted Material. + + 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. + + +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 for NonCommercial purposes + only and provided You do not Share Adapted Material; + + 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. + + 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. + + 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. + + +Section 6 -- Term and Termination. + + 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. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 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. + +======================================================================= diff --git a/src/main/java/com/songoda/epichoppers/utils/StorageContainerCache.java b/src/main/java/com/songoda/epichoppers/utils/StorageContainerCache.java index bc51322..133655c 100644 --- a/src/main/java/com/songoda/epichoppers/utils/StorageContainerCache.java +++ b/src/main/java/com/songoda/epichoppers/utils/StorageContainerCache.java @@ -1,360 +1,360 @@ -package com.songoda.epichoppers.utils; - -import com.songoda.core.compatibility.CompatibleMaterial; -import com.songoda.core.compatibility.ServerVersion; -import com.songoda.core.nms.NmsManager; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.block.BlockState; -import org.bukkit.block.data.BlockData; -import org.bukkit.block.data.type.Chest; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; - -import java.util.HashMap; -import java.util.Map; - -/** - * Persistent storage intended for streamlining read/write for storage - * containers in large batches - */ -public class StorageContainerCache { - private static final Map INVENTORY_CACHE = new HashMap<>(); - - // need to get the topmost inventory for a double chest, and save as that block - public static Cache getCachedInventory(Block block) { - Cache cache = INVENTORY_CACHE.get(block); - if (cache == null) { - Material type = block.getType(); - if (type == Material.CHEST || type == Material.TRAPPED_CHEST) { - Block b2 = findAdjacentDoubleChest(block); - //System.out.println("Adjacent to " + block + " = " + b2); - if (b2 != null && (cache = INVENTORY_CACHE.get(b2)) != null) { - return cache; - } - } - BlockState blockState = block.getState(); - if (blockState instanceof InventoryHolder) { - //System.out.println("Load " + block.getLocation()); - INVENTORY_CACHE.put(block, cache = new Cache(block, ((InventoryHolder) blockState).getInventory().getContents())); - } - } - return cache; - } - - /** - * Look for a double chest adjacent to a chest - */ - public static Block findAdjacentDoubleChest(Block block) { - if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) { - final BlockData blockData = block.getBlockData(); - if (blockData instanceof Chest) { - final Chest chest = (Chest) blockData; - if (chest.getType() != Chest.Type.SINGLE) { - // this is a double chest - check the other chest for registration data - Block other = null; - switch (chest.getFacing()) { - case SOUTH: - other = block.getRelative(chest.getType() != Chest.Type.RIGHT ? BlockFace.WEST : BlockFace.EAST); - break; - case NORTH: - other = block.getRelative(chest.getType() != Chest.Type.RIGHT ? BlockFace.EAST : BlockFace.WEST); - break; - case EAST: - other = block.getRelative(chest.getType() != Chest.Type.RIGHT ? BlockFace.SOUTH : BlockFace.NORTH); - break; - case WEST: - other = block.getRelative(chest.getType() != Chest.Type.RIGHT ? BlockFace.NORTH : BlockFace.SOUTH); - break; - default: - break; - } - // double-check - if (other != null && other.getType() == block.getType()) { - return other; - } - } - } - } else { - // legacy check - Material material = block.getType(); - BlockFace[] faces = new BlockFace[]{BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST}; - for (BlockFace face : faces) { - Block adjacentBlock = block.getRelative(face); - - if (adjacentBlock.getType() == material) { - return adjacentBlock; - } - } - } - return null; - } - - public static void update() { - INVENTORY_CACHE.entrySet().stream() - .filter(e -> e.getValue().dirty) - .forEach(e -> { - //System.out.println("Update " + e.getKey().getLocation()); - // setContents makes a copy of every item whether it's needed or not - //((InventoryHolder) e.getKey().getState()).getInventory().setContents(e.getValue().cachedInventory); - // so let's only update what needs to be updated. - final ItemStack[] cachedInventory = e.getValue().cachedInventory; - final boolean[] cacheChanged = e.getValue().cacheChanged; - Inventory inventory = ((InventoryHolder) e.getKey().getState()).getInventory();//.setContents(); - for (int i = 0; i < cachedInventory.length; i++) { - if (cacheChanged[i]) { - inventory.setItem(i, cachedInventory[i]); - } - } - - NmsManager.getWorld().updateAdjacentComparators(e.getKey()); - }); - INVENTORY_CACHE.clear(); - } - - public static class Cache { - public final Material type; - public final Block block; - public ItemStack[] cachedInventory; - public boolean[] cacheChanged; - public int[] cacheAdded; - public boolean dirty; - - public Cache(Material type, ItemStack[] cachedInventory) { - this.block = null; - this.type = type; - this.cachedInventory = cachedInventory; - this.cacheChanged = new boolean[cachedInventory.length]; - this.cacheAdded = new int[cachedInventory.length]; - } - - public Cache(Block block, ItemStack[] cachedInventory) { - this.block = block; - this.type = block.getType(); - this.cachedInventory = cachedInventory; - this.cacheChanged = new boolean[cachedInventory.length]; - this.cacheAdded = new int[cachedInventory.length]; - } - - public void setDirty(boolean dirty) { - this.dirty = dirty; - } - - public boolean isDirty() { - return this.dirty; - } - - public void setContents(ItemStack[] items) { - if (this.cachedInventory == null || items.length == this.cachedInventory.length) { - this.cachedInventory = items; - for (int i = 0; i < this.cachedInventory.length; i++) { - this.cacheChanged[i] = true; - } - this.dirty = true; - } - } - - public void setItem(int item, ItemStack itemStack) { - if (this.cachedInventory != null) { - this.cachedInventory[item] = itemStack; - this.cacheChanged[item] = true; - this.dirty = true; - } - } - - public void removeItem(int item) { - if (this.cachedInventory != null) { - this.cachedInventory[item] = null; - this.cacheChanged[item] = true; - this.dirty = true; - } - } - - public void removeItems(ItemStack item) { - if (this.cachedInventory != null && item != null) { - int toRemove = item.getAmount(); - for (int i = 0; toRemove > 0 && i < this.cachedInventory.length; i++) { - final ItemStack cacheItem = this.cachedInventory[i]; - if (cacheItem != null && cacheItem.getAmount() != 0 && item.isSimilar(cacheItem)) { - int have = cacheItem.getAmount(); - if (have > toRemove) { - this.cachedInventory[i].setAmount(have - toRemove); - this.cacheChanged[i] = true; - toRemove = 0; - } else { - this.cachedInventory[i] = null; - this.cacheChanged[i] = true; - toRemove -= have; - } - } - } - this.dirty = this.dirty | (toRemove != item.getAmount()); - } - } - - /** - * Add a number of items to this container's inventory later. - * - * @param item item to add - * @param amountToAdd how many of this item to attempt to add - * @return how many items were added - */ - public int addAny(ItemStack item, int amountToAdd) { - // Don't transfer shulker boxes into other shulker boxes, that's a bad idea. - if (this.type.name().contains("SHULKER_BOX") && item.getType().name().contains("SHULKER_BOX")) { - return 0; - } - - int totalAdded = 0; - if (this.cachedInventory != null && item != null) { - final int maxStack = item.getMaxStackSize(); - for (int i = 0; amountToAdd > 0 && i < this.cachedInventory.length; i++) { - final ItemStack cacheItem = this.cachedInventory[i]; - if (cacheItem == null || cacheItem.getAmount() == 0) { - // free slot! - int toAdd = Math.min(maxStack, amountToAdd); - this.cachedInventory[i] = item.clone(); - this.cachedInventory[i].setAmount(toAdd); - this.cacheChanged[i] = true; - this.cacheAdded[i] = toAdd; - totalAdded += toAdd; - amountToAdd -= toAdd; - } else if (maxStack > cacheItem.getAmount() && item.isSimilar(cacheItem)) { - // free space! - int toAdd = Math.min(maxStack - cacheItem.getAmount(), amountToAdd); - this.cachedInventory[i].setAmount(toAdd + cacheItem.getAmount()); - this.cacheChanged[i] = true; - this.cacheAdded[i] += toAdd; - totalAdded += toAdd; - amountToAdd -= toAdd; - } - } - if (totalAdded != 0) { - this.dirty = true; - } - } - return totalAdded; - } - - /** - * Add an item to this container's inventory later. - * - * @param item item to add - * @return true if the item was added - */ - public boolean addItem(ItemStack item) { - if (this.cachedInventory == null || item == null || item.getAmount() <= 0) { - return false; - } - - // Don't transfer shulker boxes into other shulker boxes, that's a bad idea. - if (this.type.name().contains("SHULKER_BOX") && item.getType().name().contains("SHULKER_BOX")) { - return false; - } - - // grab the amount to move and the max item stack size - int toAdd = item.getAmount(); - final int maxStack = item.getMaxStackSize(); - boolean[] check = null; - - // some destination containers have special conditions - switch (this.type.name()) { - case "BREWING_STAND": { - - // first compile a list of what slots to check - check = new boolean[5]; - String typeStr = item.getType().name().toUpperCase(); - if (typeStr.contains("POTION") || typeStr.contains("BOTTLE")) { - // potion bottles are the first three slots - check[0] = check[1] = check[2] = true; - } - // fuel in 5th position, input in 4th - if (item.getType() == Material.BLAZE_POWDER) { - check[4] = true; - } else if (CompatibleMaterial.getMaterial(item).isBrewingStandIngredient()) { - check[3] = true; - } - - break; - } - case "SMOKER": - case "BLAST_FURNACE": - case "BURNING_FURNACE": - case "FURNACE": { - - check = new boolean[3]; - - boolean isFuel = !item.getType().name().contains("LOG") && CompatibleMaterial.getMaterial(item.getType()).isFuel(); - // fuel is 2nd slot, input is first - if (isFuel) { - check[1] = true; - } else { - check[0] = true; - } - - break; - } - default: - break; - } - - // we can reduce calls to ItemStack.isSimilar() by caching what cells to look at - if (check == null) { - check = new boolean[this.cachedInventory.length]; - for (int i = 0; toAdd > 0 && i < check.length; i++) { - check[i] = true; - } - } - - // first verify that we can add this item - for (int i = 0; toAdd > 0 && i < this.cachedInventory.length; i++) { - if (check[i]) { - final ItemStack cacheItem = this.cachedInventory[i]; - if (cacheItem == null || cacheItem.getAmount() == 0) { - // free slot! - toAdd -= Math.min(maxStack, toAdd); - check[i] = true; - } else if (maxStack > cacheItem.getAmount() && item.isSimilar(cacheItem)) { - // free space! - toAdd -= Math.min(maxStack - cacheItem.getAmount(), toAdd); - check[i] = true; - } else { - check[i] = false; - } - } - } - if (toAdd <= 0) { - // all good to add! - toAdd = item.getAmount(); - for (int i = 0; toAdd > 0 && i < this.cachedInventory.length; i++) { - if (!check[i]) { - continue; - } - final ItemStack cacheItem = this.cachedInventory[i]; - if (cacheItem == null || cacheItem.getAmount() == 0) { - // free slot! - int adding = Math.min(maxStack, toAdd); - this.cachedInventory[i] = item.clone(); - this.cachedInventory[i].setAmount(adding); - this.cacheChanged[i] = true; - this.cacheAdded[i] = adding; - toAdd -= adding; - } else if (maxStack > cacheItem.getAmount()) { - // free space! - // (no need to check item.isSimilar(cacheItem), since we have that cached in check[]) - int adding = Math.min(maxStack - cacheItem.getAmount(), toAdd); - this.cachedInventory[i].setAmount(adding + cacheItem.getAmount()); - this.cacheChanged[i] = true; - this.cacheAdded[i] += adding; - toAdd -= adding; - } - } - this.dirty = true; - return true; - } - return false; - } - } -} +package com.songoda.epichoppers.utils; + +import com.songoda.core.compatibility.CompatibleMaterial; +import com.songoda.core.compatibility.ServerVersion; +import com.songoda.core.nms.NmsManager; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.type.Chest; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.Map; + +/** + * Persistent storage intended for streamlining read/write for storage + * containers in large batches + */ +public class StorageContainerCache { + private static final Map INVENTORY_CACHE = new HashMap<>(); + + // need to get the topmost inventory for a double chest, and save as that block + public static Cache getCachedInventory(Block block) { + Cache cache = INVENTORY_CACHE.get(block); + if (cache == null) { + Material type = block.getType(); + if (type == Material.CHEST || type == Material.TRAPPED_CHEST) { + Block b2 = findAdjacentDoubleChest(block); + //System.out.println("Adjacent to " + block + " = " + b2); + if (b2 != null && (cache = INVENTORY_CACHE.get(b2)) != null) { + return cache; + } + } + BlockState blockState = block.getState(); + if (blockState instanceof InventoryHolder) { + //System.out.println("Load " + block.getLocation()); + INVENTORY_CACHE.put(block, cache = new Cache(block, ((InventoryHolder) blockState).getInventory().getContents())); + } + } + return cache; + } + + /** + * Look for a double chest adjacent to a chest + */ + public static Block findAdjacentDoubleChest(Block block) { + if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) { + final BlockData blockData = block.getBlockData(); + if (blockData instanceof Chest) { + final Chest chest = (Chest) blockData; + if (chest.getType() != Chest.Type.SINGLE) { + // this is a double chest - check the other chest for registration data + Block other = null; + switch (chest.getFacing()) { + case SOUTH: + other = block.getRelative(chest.getType() != Chest.Type.RIGHT ? BlockFace.WEST : BlockFace.EAST); + break; + case NORTH: + other = block.getRelative(chest.getType() != Chest.Type.RIGHT ? BlockFace.EAST : BlockFace.WEST); + break; + case EAST: + other = block.getRelative(chest.getType() != Chest.Type.RIGHT ? BlockFace.SOUTH : BlockFace.NORTH); + break; + case WEST: + other = block.getRelative(chest.getType() != Chest.Type.RIGHT ? BlockFace.NORTH : BlockFace.SOUTH); + break; + default: + break; + } + // double-check + if (other != null && other.getType() == block.getType()) { + return other; + } + } + } + } else { + // legacy check + Material material = block.getType(); + BlockFace[] faces = new BlockFace[]{BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST}; + for (BlockFace face : faces) { + Block adjacentBlock = block.getRelative(face); + + if (adjacentBlock.getType() == material) { + return adjacentBlock; + } + } + } + return null; + } + + public static void update() { + INVENTORY_CACHE.entrySet().stream() + .filter(e -> e.getValue().dirty) + .forEach(e -> { + //System.out.println("Update " + e.getKey().getLocation()); + // setContents makes a copy of every item whether it's needed or not + //((InventoryHolder) e.getKey().getState()).getInventory().setContents(e.getValue().cachedInventory); + // so let's only update what needs to be updated. + final ItemStack[] cachedInventory = e.getValue().cachedInventory; + final boolean[] cacheChanged = e.getValue().cacheChanged; + Inventory inventory = ((InventoryHolder) e.getKey().getState()).getInventory();//.setContents(); + for (int i = 0; i < cachedInventory.length; i++) { + if (cacheChanged[i]) { + inventory.setItem(i, cachedInventory[i]); + } + } + + NmsManager.getWorld().updateAdjacentComparators(e.getKey()); + }); + INVENTORY_CACHE.clear(); + } + + public static class Cache { + public final Material type; + public final Block block; + public ItemStack[] cachedInventory; + public boolean[] cacheChanged; + public int[] cacheAdded; + public boolean dirty; + + public Cache(Material type, ItemStack[] cachedInventory) { + this.block = null; + this.type = type; + this.cachedInventory = cachedInventory; + this.cacheChanged = new boolean[cachedInventory.length]; + this.cacheAdded = new int[cachedInventory.length]; + } + + public Cache(Block block, ItemStack[] cachedInventory) { + this.block = block; + this.type = block.getType(); + this.cachedInventory = cachedInventory; + this.cacheChanged = new boolean[cachedInventory.length]; + this.cacheAdded = new int[cachedInventory.length]; + } + + public void setDirty(boolean dirty) { + this.dirty = dirty; + } + + public boolean isDirty() { + return this.dirty; + } + + public void setContents(ItemStack[] items) { + if (this.cachedInventory == null || items.length == this.cachedInventory.length) { + this.cachedInventory = items; + for (int i = 0; i < this.cachedInventory.length; i++) { + this.cacheChanged[i] = true; + } + this.dirty = true; + } + } + + public void setItem(int item, ItemStack itemStack) { + if (this.cachedInventory != null) { + this.cachedInventory[item] = itemStack; + this.cacheChanged[item] = true; + this.dirty = true; + } + } + + public void removeItem(int item) { + if (this.cachedInventory != null) { + this.cachedInventory[item] = null; + this.cacheChanged[item] = true; + this.dirty = true; + } + } + + public void removeItems(ItemStack item) { + if (this.cachedInventory != null && item != null) { + int toRemove = item.getAmount(); + for (int i = 0; toRemove > 0 && i < this.cachedInventory.length; i++) { + final ItemStack cacheItem = this.cachedInventory[i]; + if (cacheItem != null && cacheItem.getAmount() != 0 && item.isSimilar(cacheItem)) { + int have = cacheItem.getAmount(); + if (have > toRemove) { + this.cachedInventory[i].setAmount(have - toRemove); + this.cacheChanged[i] = true; + toRemove = 0; + } else { + this.cachedInventory[i] = null; + this.cacheChanged[i] = true; + toRemove -= have; + } + } + } + this.dirty = this.dirty | (toRemove != item.getAmount()); + } + } + + /** + * Add a number of items to this container's inventory later. + * + * @param item item to add + * @param amountToAdd how many of this item to attempt to add + * @return how many items were added + */ + public int addAny(ItemStack item, int amountToAdd) { + // Don't transfer shulker boxes into other shulker boxes, that's a bad idea. + if (this.type.name().contains("SHULKER_BOX") && item.getType().name().contains("SHULKER_BOX")) { + return 0; + } + + int totalAdded = 0; + if (this.cachedInventory != null && item != null) { + final int maxStack = item.getMaxStackSize(); + for (int i = 0; amountToAdd > 0 && i < this.cachedInventory.length; i++) { + final ItemStack cacheItem = this.cachedInventory[i]; + if (cacheItem == null || cacheItem.getAmount() == 0) { + // free slot! + int toAdd = Math.min(maxStack, amountToAdd); + this.cachedInventory[i] = item.clone(); + this.cachedInventory[i].setAmount(toAdd); + this.cacheChanged[i] = true; + this.cacheAdded[i] = toAdd; + totalAdded += toAdd; + amountToAdd -= toAdd; + } else if (maxStack > cacheItem.getAmount() && item.isSimilar(cacheItem)) { + // free space! + int toAdd = Math.min(maxStack - cacheItem.getAmount(), amountToAdd); + this.cachedInventory[i].setAmount(toAdd + cacheItem.getAmount()); + this.cacheChanged[i] = true; + this.cacheAdded[i] += toAdd; + totalAdded += toAdd; + amountToAdd -= toAdd; + } + } + if (totalAdded != 0) { + this.dirty = true; + } + } + return totalAdded; + } + + /** + * Add an item to this container's inventory later. + * + * @param item item to add + * @return true if the item was added + */ + public boolean addItem(ItemStack item) { + if (this.cachedInventory == null || item == null || item.getAmount() <= 0) { + return false; + } + + // Don't transfer shulker boxes into other shulker boxes, that's a bad idea. + if (this.type.name().contains("SHULKER_BOX") && item.getType().name().contains("SHULKER_BOX")) { + return false; + } + + // grab the amount to move and the max item stack size + int toAdd = item.getAmount(); + final int maxStack = item.getMaxStackSize(); + boolean[] check = null; + + // some destination containers have special conditions + switch (this.type.name()) { + case "BREWING_STAND": { + + // first compile a list of what slots to check + check = new boolean[5]; + String typeStr = item.getType().name().toUpperCase(); + if (typeStr.contains("POTION") || typeStr.contains("BOTTLE")) { + // potion bottles are the first three slots + check[0] = check[1] = check[2] = true; + } + // fuel in 5th position, input in 4th + if (item.getType() == Material.BLAZE_POWDER) { + check[4] = true; + } else if (CompatibleMaterial.getMaterial(item).isBrewingStandIngredient()) { + check[3] = true; + } + + break; + } + case "SMOKER": + case "BLAST_FURNACE": + case "BURNING_FURNACE": + case "FURNACE": { + + check = new boolean[3]; + + boolean isFuel = !item.getType().name().contains("LOG") && CompatibleMaterial.getMaterial(item.getType()).isFuel(); + // fuel is 2nd slot, input is first + if (isFuel) { + check[1] = true; + } else { + check[0] = true; + } + + break; + } + default: + break; + } + + // we can reduce calls to ItemStack.isSimilar() by caching what cells to look at + if (check == null) { + check = new boolean[this.cachedInventory.length]; + for (int i = 0; toAdd > 0 && i < check.length; i++) { + check[i] = true; + } + } + + // first verify that we can add this item + for (int i = 0; toAdd > 0 && i < this.cachedInventory.length; i++) { + if (check[i]) { + final ItemStack cacheItem = this.cachedInventory[i]; + if (cacheItem == null || cacheItem.getAmount() == 0) { + // free slot! + toAdd -= Math.min(maxStack, toAdd); + check[i] = true; + } else if (maxStack > cacheItem.getAmount() && item.isSimilar(cacheItem)) { + // free space! + toAdd -= Math.min(maxStack - cacheItem.getAmount(), toAdd); + check[i] = true; + } else { + check[i] = false; + } + } + } + if (toAdd <= 0) { + // all good to add! + toAdd = item.getAmount(); + for (int i = 0; toAdd > 0 && i < this.cachedInventory.length; i++) { + if (!check[i]) { + continue; + } + final ItemStack cacheItem = this.cachedInventory[i]; + if (cacheItem == null || cacheItem.getAmount() == 0) { + // free slot! + int adding = Math.min(maxStack, toAdd); + this.cachedInventory[i] = item.clone(); + this.cachedInventory[i].setAmount(adding); + this.cacheChanged[i] = true; + this.cacheAdded[i] = adding; + toAdd -= adding; + } else if (maxStack > cacheItem.getAmount()) { + // free space! + // (no need to check item.isSimilar(cacheItem), since we have that cached in check[]) + int adding = Math.min(maxStack - cacheItem.getAmount(), toAdd); + this.cachedInventory[i].setAmount(adding + cacheItem.getAmount()); + this.cacheChanged[i] = true; + this.cacheAdded[i] += adding; + toAdd -= adding; + } + } + this.dirty = true; + return true; + } + return false; + } + } +}