From 6030061826e5d163a3d9562ff6045b6143c519f6 Mon Sep 17 00:00:00 2001 From: wjwrh Date: Mon, 25 May 2020 07:41:30 +0800 Subject: [PATCH] [challenges] Minecraft by Ruby --- .../main/java/org/abc/A/B/DisplayItemAPI.java | 41 + .../main/java/org/abc/A/B/QuickShopAPI.java | 54 + .../src/main/java/org/abc/A/B/ShopAPI.java | 108 ++ .../main/java/org/abc/A/B/package-info.java | 7 + .../src/main/java/org/abc/A/BootError.java | 65 + .../main/java/org/abc/A/BuiltInSolution.java | 71 + .../java/org/abc/A/C/InternalListener.java | 104 ++ .../src/main/java/org/abc/A/Cache.java | 105 ++ .../src/main/java/org/abc/A/CacheFlag.java | 7 + .../java/org/abc/A/D/CommandContainer.java | 39 + .../main/java/org/abc/A/D/CommandManager.java | 396 +++++ .../java/org/abc/A/D/CommandProcesser.java | 58 + .../abc/A/D/subcommand/SubCommand_About.java | 125 ++ .../abc/A/D/subcommand/SubCommand_Amount.java | 70 + .../abc/A/D/subcommand/SubCommand_Buy.java | 85 + .../abc/A/D/subcommand/SubCommand_Clean.java | 90 + .../A/D/subcommand/SubCommand_CleanGhost.java | 145 ++ .../abc/A/D/subcommand/SubCommand_Create.java | 139 ++ .../abc/A/D/subcommand/SubCommand_Debug.java | 146 ++ .../abc/A/D/subcommand/SubCommand_Empty.java | 93 + .../abc/A/D/subcommand/SubCommand_Export.java | 81 + .../D/subcommand/SubCommand_FetchMessage.java | 59 + .../abc/A/D/subcommand/SubCommand_Find.java | 130 ++ .../abc/A/D/subcommand/SubCommand_Help.java | 74 + .../abc/A/D/subcommand/SubCommand_Info.java | 109 ++ .../abc/A/D/subcommand/SubCommand_Paste.java | 87 + .../abc/A/D/subcommand/SubCommand_Price.java | 225 +++ .../abc/A/D/subcommand/SubCommand_ROOT.java | 81 + .../A/D/subcommand/SubCommand_Recovery.java | 70 + .../abc/A/D/subcommand/SubCommand_Refill.java | 96 ++ .../abc/A/D/subcommand/SubCommand_Reload.java | 50 + .../abc/A/D/subcommand/SubCommand_Remove.java | 85 + .../abc/A/D/subcommand/SubCommand_Reset.java | 91 + .../abc/A/D/subcommand/SubCommand_Sell.java | 82 + .../A/D/subcommand/SubCommand_SetOwner.java | 91 + .../A/D/subcommand/SubCommand_SilentBuy.java | 78 + .../D/subcommand/SubCommand_SilentEmpty.java | 83 + .../subcommand/SubCommand_SilentPreview.java | 79 + .../D/subcommand/SubCommand_SilentRemove.java | 81 + .../A/D/subcommand/SubCommand_SilentSell.java | 78 + .../SubCommand_SilentUnlimited.java | 80 + .../abc/A/D/subcommand/SubCommand_Staff.java | 191 +++ .../D/subcommand/SubCommand_SuperCreate.java | 130 ++ .../A/D/subcommand/SubCommand_Unlimited.java | 86 + .../abc/A/D/subcommand/SubCommand_Update.java | 107 ++ .../java/org/abc/A/E/BufferStatement.java | 79 + .../src/main/java/org/abc/A/E/Database.java | 187 ++ .../main/java/org/abc/A/E/DatabaseCore.java | 34 + .../main/java/org/abc/A/E/DatabaseHelper.java | 259 +++ .../java/org/abc/A/E/DatabaseManager.java | 162 ++ .../main/java/org/abc/A/E/DatabaseTask.java | 55 + .../src/main/java/org/abc/A/E/MySQLCore.java | 126 ++ .../src/main/java/org/abc/A/E/SQLiteCore.java | 135 ++ .../src/main/java/org/abc/A/F/Economy.java | 91 + .../main/java/org/abc/A/F/EconomyCore.java | 79 + .../main/java/org/abc/A/F/EconomyType.java | 57 + .../main/java/org/abc/A/F/Economy_Mixed.java | 93 + .../java/org/abc/A/F/Economy_Reserve.java | 180 ++ .../main/java/org/abc/A/F/Economy_Vault.java | 258 +++ .../org/abc/A/G/ProtectionCheckStatus.java | 31 + .../src/main/java/org/abc/A/G/QSEvent.java | 40 + .../main/java/org/abc/A/G/ShopClickEvent.java | 60 + .../java/org/abc/A/G/ShopCreateEvent.java | 61 + .../java/org/abc/A/G/ShopDeleteEvent.java | 59 + .../abc/A/G/ShopDisplayItemDespawnEvent.java | 84 + .../abc/A/G/ShopDisplayItemSpawnEvent.java | 84 + .../abc/A/G/ShopInventoryPreviewEvent.java | 61 + .../main/java/org/abc/A/G/ShopLoadEvent.java | 57 + .../abc/A/G/ShopModeratorChangedEvent.java | 51 + .../java/org/abc/A/G/ShopPreCreateEvent.java | 66 + .../org/abc/A/G/ShopPriceChangeEvent.java | 67 + .../org/abc/A/G/ShopProtectionCheckEvent.java | 75 + .../java/org/abc/A/G/ShopPurchaseEvent.java | 67 + .../org/abc/A/G/ShopSignUpdatedEvent.java | 51 + .../org/abc/A/G/ShopSuccessPurchaseEvent.java | 98 ++ .../java/org/abc/A/G/ShopUnloadEvent.java | 44 + .../java/org/abc/A/G/ShopUpdateEvent.java | 54 + .../java/org/abc/A/H/newest/ConfigFile.java | 18 + .../java/org/abc/A/H/newest/LanguageFile.java | 38 + .../java/org/abc/A/H/old/FileEnvelope.java | 245 +++ .../src/main/java/org/abc/A/H/old/IFile.java | 204 +++ .../main/java/org/abc/A/H/old/JSONFile.java | 36 + .../main/java/org/abc/A/H/old/YAMLFile.java | 35 + .../FactionsUUID/FactionsUUIDIntegration.java | 213 +++ .../main/java/org/abc/A/I/IntegrateStage.java | 29 + .../java/org/abc/A/I/IntegratedPlugin.java | 38 + .../java/org/abc/A/I/IntegrationStage.java | 33 + .../I/PlotSquared/PlotSquaredIntegration.java | 92 + .../A/I/Residence/ResidenceIntegration.java | 141 ++ .../java/org/abc/A/I/Towny/TownyFlags.java | 41 + .../org/abc/A/I/Towny/TownyIntegration.java | 109 ++ .../abc/A/I/WorldGuard/WorldGuardFlags.java | 42 + .../A/I/WorldGuard/WorldGuardIntegration.java | 181 ++ .../main/java/org/abc/A/J/BlockListener.java | 267 +++ .../main/java/org/abc/A/J/ChatListener.java | 56 + .../main/java/org/abc/A/J/ChunkListener.java | 70 + .../java/org/abc/A/J/ClearLaggListener.java | 53 + .../org/abc/A/J/CustomInventoryListener.java | 102 ++ .../org/abc/A/J/DisplayBugFixListener.java | 65 + .../abc/A/J/DisplayProtectionListener.java | 656 +++++++ .../main/java/org/abc/A/J/LockListener.java | 235 +++ .../main/java/org/abc/A/J/PlayerListener.java | 380 +++++ .../org/abc/A/J/ProtectionListenerBase.java | 68 + .../org/abc/A/J/ShopProtectionListener.java | 271 +++ .../main/java/org/abc/A/J/WorldListener.java | 116 ++ .../org/abc/A/K/MckFileConfiguration.java | 25 + .../JsonConfiguration/JSONConfiguration.java | 195 +++ .../JSONConfigurationOptions.java | 66 + .../JsonConfiguration/SerializableSet.java | 151 ++ .../SerializationHelper.java | 170 ++ .../sk89q/worldedit/util/net/HttpRequest.java | 500 ++++++ .../worldedit/util/paste/EngineHubPaster.java | 80 + .../L/de/Keyle/MyPet/api/util/Colorizer.java | 56 + .../L/de/Keyle/MyPet/api/util/LogFormat.java | 61 + .../Keyle/MyPet/api/util/ReflectionUtil.java | 120 ++ .../lucko/spark/common/util/FormatUtil.java | 19 + .../spark/common/util/TypeDescriptors.java | 58 + .../src/main/java/org/abc/A/Language.java | 91 + .../java/org/abc/A/M/BukkitPermsProvider.java | 50 + .../A/M/PermissionInfomationContainer.java | 53 + .../java/org/abc/A/M/PermissionManager.java | 81 + .../java/org/abc/A/M/PermissionProvider.java | 54 + .../org/abc/A/M/PermissionProviderType.java | 44 + .../org/abc/A/M/ProviderIsEmptyException.java | 32 + .../org/abc/A/M/VaultPermissionProvider.java | 84 + .../src/main/java/org/abc/A/Metrics.java | 760 +++++++++ .../org/abc/A/N/ArmorStandDisplayItem.java | 331 ++++ .../main/java/org/abc/A/N/ContainerShop.java | 1036 +++++++++++ .../main/java/org/abc/A/N/DisplayItem.java | 307 ++++ .../A/N/DisplayItemPersistentDataType.java | 70 + .../main/java/org/abc/A/N/DisplayType.java | 72 + .../src/main/java/org/abc/A/N/Info.java | 138 ++ .../java/org/abc/A/N/InventoryPreview.java | 140 ++ .../java/org/abc/A/N/MatcherWorkMode.java | 55 + .../java/org/abc/A/N/RealDisplayItem.java | 252 +++ .../src/main/java/org/abc/A/N/Shop.java | 337 ++++ .../src/main/java/org/abc/A/N/ShopAction.java | 27 + .../src/main/java/org/abc/A/N/ShopChunk.java | 47 + .../src/main/java/org/abc/A/N/ShopLoader.java | 514 ++++++ .../main/java/org/abc/A/N/ShopManager.java | 1117 ++++++++++++ .../main/java/org/abc/A/N/ShopModerator.java | 189 ++ .../java/org/abc/A/N/ShopProtectionFlag.java | 47 + .../src/main/java/org/abc/A/N/ShopType.java | 51 + .../java/org/abc/A/N/VirtualDisplayItem.java | 377 ++++ .../abc/A/O/DisplayAutoDespawnWatcher.java | 79 + .../abc/A/O/DisplayDupeRemoverWatcher.java | 43 + .../main/java/org/abc/A/O/DisplayWatcher.java | 58 + .../org/abc/A/O/InventoryEditContainer.java | 38 + .../src/main/java/org/abc/A/O/LogWatcher.java | 100 ++ .../java/org/abc/A/O/OngoingFeeWatcher.java | 106 ++ .../org/abc/A/O/ShopContainerWatcher.java | 57 + .../java/org/abc/A/O/SignUpdateWatcher.java | 48 + .../java/org/abc/A/O/SyncTaskWatcher.java | 92 + .../main/java/org/abc/A/O/UpdateWatcher.java | 198 +++ .../src/main/java/org/abc/A/QuickShop.java | 1518 +++++++++++++++++ .../main/java/org/abc/A/ServiceInjector.java | 49 + .../java/org/abc/A/util/ChatSheetPrinter.java | 92 + .../src/main/java/org/abc/A/util/Copied.java | 55 + .../java/org/abc/A/util/FunnyEasterEgg.java | 464 +++++ .../org/abc/A/util/IncompatibleChecker.java | 97 ++ .../org/abc/A/util/IntegrationHelper.java | 127 ++ .../src/main/java/org/abc/A/util/ItemNMS.java | 83 + .../Language/Game/BukkitGameLanguageImpl.java | 57 + .../A/util/Language/Game/GameLanguage.java | 19 + .../Game/InternalGameLanguageImpl.java | 51 + .../Language/Game/MojangGameLanguageImpl.java | 266 +++ .../src/main/java/org/abc/A/util/MsgUtil.java | 1379 +++++++++++++++ .../org/abc/A/util/PermissionChecker.java | 124 ++ .../java/org/abc/A/util/ReflectFactory.java | 46 + .../main/java/org/abc/A/util/RomanNumber.java | 54 + .../org/abc/A/util/SentryErrorReporter.java | 387 +++++ .../src/main/java/org/abc/A/util/Timer.java | 93 + .../java/org/abc/A/util/UpdateInfomation.java | 38 + .../src/main/java/org/abc/A/util/Updater.java | 148 ++ .../src/main/java/org/abc/A/util/Util.java | 1407 +++++++++++++++ .../java/org/abc/A/util/WarningSender.java | 63 + .../util/bukkitwrapper/BukkitAPIWrapper.java | 48 + .../A/util/bukkitwrapper/SpigotWrapper.java | 65 + .../compatibility/CompatibilityManager.java | 29 + .../compatibility/CompatibilityModule.java | 26 + .../compatibility/NCPCompatibilityModule.java | 58 + .../java/org/abc/A/util/github/GithubAPI.java | 62 + .../A/util/github/ReleaseJsonContainer.java | 106 ++ .../org/abc/A/util/location/LocationOf.java | 41 + .../org/abc/A/util/location/StringOf.java | 44 + .../abc/A/util/logger/QuickShopLogger.java | 317 ++++ .../matcher/item/BukkitItemMatcherImpl.java | 51 + .../abc/A/util/matcher/item/ItemMatcher.java | 28 + .../item/QuickShopItemMatcherImpl.java | 549 ++++++ .../org/abc/A/util/mojangapi/AssetJson.java | 73 + .../org/abc/A/util/mojangapi/MojangAPI.java | 126 ++ .../abc/A/util/mojangapi/PerVersionJson.java | 805 +++++++++ .../org/abc/A/util/mojangapi/VersionList.java | 158 ++ .../org/abc/A/util/paste/EngineHubPaster.java | 33 + .../main/java/org/abc/A/util/paste/Paste.java | 398 +++++ .../org/abc/A/util/paste/PasteInterface.java | 27 + .../org/abc/A/util/paste/UbuntuPaster.java | 71 + .../src/main/resources/config.yml | 509 ++++++ .../src/main/resources/enchi18n.yml | 0 .../src/main/resources/itemi18n.yml | 0 .../resources/lang-original/messages.json | 252 +++ .../main/resources/lang/af-ZA/messages.json | 252 +++ .../main/resources/lang/ar-SA/messages.json | 252 +++ .../main/resources/lang/ca-ES/messages.json | 252 +++ .../main/resources/lang/cs-CZ/messages.json | 252 +++ .../main/resources/lang/da-DK/messages.json | 252 +++ .../main/resources/lang/de-DE/messages.json | 252 +++ .../main/resources/lang/el-GR/messages.json | 252 +++ .../main/resources/lang/en-US/messages.json | 252 +++ .../main/resources/lang/es-ES/messages.json | 252 +++ .../main/resources/lang/fi-FI/messages.json | 252 +++ .../main/resources/lang/fr-FR/messages.json | 252 +++ .../main/resources/lang/he-IL/messages.json | 252 +++ .../main/resources/lang/hu-HU/messages.json | 252 +++ .../main/resources/lang/it-IT/messages.json | 252 +++ .../main/resources/lang/ja-JP/messages.json | 252 +++ .../main/resources/lang/ko-KR/messages.json | 252 +++ .../main/resources/lang/nl-NL/messages.json | 252 +++ .../main/resources/lang/no-NO/messages.json | 252 +++ .../main/resources/lang/pl-PL/messages.json | 252 +++ .../main/resources/lang/pt-BR/messages.json | 252 +++ .../main/resources/lang/pt-PT/messages.json | 252 +++ .../main/resources/lang/ro-RO/messages.json | 252 +++ .../main/resources/lang/ru-RU/messages.json | 252 +++ .../main/resources/lang/sr-SP/messages.json | 252 +++ .../main/resources/lang/sv-SE/messages.json | 252 +++ .../main/resources/lang/tr-TR/messages.json | 252 +++ .../main/resources/lang/uk-UA/messages.json | 252 +++ .../main/resources/lang/vi-VN/messages.json | 252 +++ .../main/resources/lang/zh-CN/messages.json | 252 +++ .../main/resources/lang/zh-TW/messages.json | 252 +++ .../src/main/resources/messages/de.json | 234 +++ .../src/main/resources/messages/en-US.json | 234 +++ .../src/main/resources/messages/en.json | 234 +++ .../src/main/resources/messages/es-419.json | 234 +++ .../src/main/resources/messages/fi.json | 234 +++ .../src/main/resources/messages/fr.json | 234 +++ .../src/main/resources/messages/it.json | 234 +++ .../src/main/resources/messages/ja.json | 234 +++ .../src/main/resources/messages/ko.json | 234 +++ .../src/main/resources/messages/pl.json | 234 +++ .../src/main/resources/messages/ru.json | 234 +++ .../src/main/resources/messages/tr.json | 234 +++ .../src/main/resources/messages/zh-CN.json | 234 +++ .../src/main/resources/messages/zh-TW.json | 234 +++ .../src/main/resources/plugin.yml | 128 ++ .../src/main/resources/potioni18n.yml | 1 + 247 files changed, 41225 insertions(+) create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/DisplayItemAPI.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/QuickShopAPI.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/ShopAPI.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/package-info.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/BootError.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/BuiltInSolution.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/C/InternalListener.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/Cache.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/CacheFlag.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/CommandContainer.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/CommandManager.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/CommandProcesser.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_About.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Amount.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Buy.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Clean.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_CleanGhost.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Create.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Debug.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Empty.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Export.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_FetchMessage.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Find.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Help.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Info.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Paste.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Price.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_ROOT.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Recovery.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Refill.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Reload.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Remove.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Reset.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Sell.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SetOwner.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentBuy.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentEmpty.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentPreview.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentRemove.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentSell.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentUnlimited.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Staff.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SuperCreate.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Unlimited.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Update.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/BufferStatement.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/Database.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseCore.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseHelper.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseManager.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseTask.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/MySQLCore.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/SQLiteCore.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/EconomyCore.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/EconomyType.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy_Mixed.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy_Reserve.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy_Vault.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ProtectionCheckStatus.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/QSEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopClickEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopCreateEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopDeleteEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopDisplayItemDespawnEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopDisplayItemSpawnEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopInventoryPreviewEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopLoadEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopModeratorChangedEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopPreCreateEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopPriceChangeEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopProtectionCheckEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopPurchaseEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopSignUpdatedEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopSuccessPurchaseEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopUnloadEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopUpdateEvent.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/newest/ConfigFile.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/newest/LanguageFile.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/FileEnvelope.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/IFile.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/JSONFile.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/YAMLFile.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/FactionsUUID/FactionsUUIDIntegration.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/IntegrateStage.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/IntegratedPlugin.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/IntegrationStage.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/PlotSquared/PlotSquaredIntegration.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/Residence/ResidenceIntegration.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/Towny/TownyFlags.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/Towny/TownyIntegration.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/WorldGuard/WorldGuardFlags.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/WorldGuard/WorldGuardIntegration.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/BlockListener.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ChatListener.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ChunkListener.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ClearLaggListener.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/CustomInventoryListener.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/DisplayBugFixListener.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/DisplayProtectionListener.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/LockListener.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/PlayerListener.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ProtectionListenerBase.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ShopProtectionListener.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/WorldListener.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/K/MckFileConfiguration.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/JSONConfiguration.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/JSONConfigurationOptions.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/SerializableSet.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/SerializationHelper.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/sk89q/worldedit/util/net/HttpRequest.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/sk89q/worldedit/util/paste/EngineHubPaster.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/de/Keyle/MyPet/api/util/Colorizer.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/de/Keyle/MyPet/api/util/LogFormat.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/de/Keyle/MyPet/api/util/ReflectionUtil.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/me/lucko/spark/common/util/FormatUtil.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/me/lucko/spark/common/util/TypeDescriptors.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/Language.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/BukkitPermsProvider.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionInfomationContainer.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionManager.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionProvider.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionProviderType.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/ProviderIsEmptyException.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/VaultPermissionProvider.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/Metrics.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ArmorStandDisplayItem.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ContainerShop.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/DisplayItem.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/DisplayItemPersistentDataType.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/DisplayType.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/Info.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/InventoryPreview.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/MatcherWorkMode.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/RealDisplayItem.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/Shop.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopAction.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopChunk.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopLoader.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopManager.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopModerator.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopProtectionFlag.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopType.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/VirtualDisplayItem.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/DisplayAutoDespawnWatcher.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/DisplayDupeRemoverWatcher.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/DisplayWatcher.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/InventoryEditContainer.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/LogWatcher.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/OngoingFeeWatcher.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/ShopContainerWatcher.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/SignUpdateWatcher.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/SyncTaskWatcher.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/UpdateWatcher.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/QuickShop.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/ServiceInjector.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/ChatSheetPrinter.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Copied.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/FunnyEasterEgg.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/IncompatibleChecker.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/IntegrationHelper.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/ItemNMS.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/BukkitGameLanguageImpl.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/GameLanguage.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/InternalGameLanguageImpl.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/MojangGameLanguageImpl.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/MsgUtil.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/PermissionChecker.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/ReflectFactory.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/RomanNumber.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/SentryErrorReporter.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Timer.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/UpdateInfomation.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Updater.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Util.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/WarningSender.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/bukkitwrapper/BukkitAPIWrapper.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/bukkitwrapper/SpigotWrapper.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/compatibility/CompatibilityManager.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/compatibility/CompatibilityModule.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/compatibility/NCPCompatibilityModule.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/github/GithubAPI.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/github/ReleaseJsonContainer.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/location/LocationOf.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/location/StringOf.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/logger/QuickShopLogger.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/matcher/item/BukkitItemMatcherImpl.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/matcher/item/ItemMatcher.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/matcher/item/QuickShopItemMatcherImpl.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/AssetJson.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/MojangAPI.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/PerVersionJson.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/VersionList.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/EngineHubPaster.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/Paste.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/PasteInterface.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/UbuntuPaster.java create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/config.yml create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/enchi18n.yml create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/itemi18n.yml create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang-original/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/af-ZA/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ar-SA/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ca-ES/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/cs-CZ/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/da-DK/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/de-DE/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/el-GR/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/en-US/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/es-ES/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/fi-FI/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/fr-FR/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/he-IL/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/hu-HU/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/it-IT/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ja-JP/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ko-KR/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/nl-NL/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/no-NO/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/pl-PL/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/pt-BR/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/pt-PT/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ro-RO/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ru-RU/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/sr-SP/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/sv-SE/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/tr-TR/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/uk-UA/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/vi-VN/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/zh-CN/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/zh-TW/messages.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/de.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/en-US.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/en.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/es-419.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/fi.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/fr.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/it.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/ja.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/ko.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/pl.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/ru.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/tr.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/zh-CN.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/zh-TW.json create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/plugin.yml create mode 100644 challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/potioni18n.yml diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/DisplayItemAPI.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/DisplayItemAPI.java new file mode 100644 index 0000000..12e99b3 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/DisplayItemAPI.java @@ -0,0 +1,41 @@ +package org.abc.A.B; + +import lombok.AllArgsConstructor; +import org.abc.A.N.DisplayItem; +import org.abc.A.N.DisplayType; +import org.abc.A.N.Shop; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.abc.A.QuickShop; + +@AllArgsConstructor +public class DisplayItemAPI { + private QuickShop plugin; + + /** + * Checks is a display item + * @param itemStack The itemstack + * @return yes or no + */ + public static boolean isDisplayItem(@NotNull ItemStack itemStack){ + return DisplayItem.checkIsGuardItemStack(itemStack); + } + + /** + * Check is a shop's display item + * @param itemStack The itemstack + * @param shop The itemstack + * @return yes or no + */ + public static boolean isShopDisplayItem(@NotNull ItemStack itemStack, @NotNull Shop shop){ + return DisplayItem.checkIsTargetShopDisplay(itemStack,shop); + } + + /** + * Gets the display type now using + * @return The type of display now using + */ + public static DisplayType getNowUsing(){ + return DisplayItem.getNowUsing(); + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/QuickShopAPI.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/QuickShopAPI.java new file mode 100644 index 0000000..a0892a6 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/QuickShopAPI.java @@ -0,0 +1,54 @@ +package org.abc.A.B; + +import org.abc.A.util.IntegrationHelper; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.QuickShop; +import org.abc.A.util.compatibility.CompatibilityManager; + +public class QuickShopAPI { + private static QuickShop plugin; + + /** + * DO NOT CALL ME, IT JUST A INTERNAL METHOD, BUT BECAUSE CROSS-PACKAGE ACCESS, IT IS PUBLIC, SO DO NOT EXECUTE IT. + * Go away =w= + * @param qs The QuickShop plugin instance + */ + public static void setupApi(@NotNull QuickShop qs){ + plugin = qs; + } + + /** + * Gets apis about shop + * @return The Shop API + */ + public static @NotNull ShopAPI getShopAPI(){ + return new ShopAPI(plugin); + } + + /** + * Gets apis about display item + * @return The DisplayItem API + */ + public static @NotNull DisplayItemAPI getDisplayItemAPI(){ + return new DisplayItemAPI(plugin); + } + + /** + * Gets anti-cheat compatibility manager to allow you access and process. + * If you calling this before plugin loaded up, you might get nothing. + * @return Compatibility Manager + */ + public static @Nullable CompatibilityManager getCompatibilityManager(){ + return plugin.getCompatibilityTool(); + } + + /** + * Gets protection plugins integration helper to allow hook your plugin to our checks system. + * If you calling this before plugin loaded up, you might get nothing. + * @return IntegrationHelper + */ + public static @Nullable IntegrationHelper getIntegrationManager(){ + return plugin.getIntegrationHelper(); + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/ShopAPI.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/ShopAPI.java new file mode 100644 index 0000000..872fa62 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/ShopAPI.java @@ -0,0 +1,108 @@ +package org.abc.A.B; + +import lombok.AllArgsConstructor; +import org.abc.A.N.Shop; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.QuickShop; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +@AllArgsConstructor +public class ShopAPI { + private QuickShop plugin; + + /** + * Gets shop from location + * @param location The location + * @return The shop in that location, may be null + */ + public @Nullable Shop getShop(@NotNull Location location){ + return plugin.getShopManager().getShop(location,false); + } + /** + * Gets shop from location with caching + * @param location The location + * @return The shop in that location, may be null + */ + public @Nullable Shop getShopWithCaching(@NotNull Location location){ + if(plugin.getShopCache() == null){ + return getShop(location); + } + return plugin.getShopCache().getCaching(location,false); + } + + /** + * Gets shops in chunk + * @param chunk The chunk + * @return The shops in chunk, may be null + */ + public @Nullable Map getShop(@NotNull Chunk chunk){ + return plugin.getShopManager().getShops(chunk); + } + + /** + * Gets shop from location + * @param location The location + * @return The shop in that location, may be null + */ + public @Nullable Shop getShopIncludeAttached(@NotNull Location location){ + return plugin.getShopManager().getShopIncludeAttached(location); + } + /** + * Gets shop from location and use caching + * @param location The location + * @return The shop in that location, may be null + */ + public @Nullable Shop getShopIncludeAttachedWithCaching(@NotNull Location location){ + if(plugin.getShopCache() == null){ + return getShopIncludeAttached(location); + } + return plugin.getShopCache().getCaching(location,true); + } + + /** + * Gets a list of copy for loaded shops + * This is a expensive action, please caching the result + * @return The copy of loaded shops + */ + public @NotNull List getLoadedShops(){ + return new ArrayList<>(plugin.getShopManager().getLoadedShops()); + } + + /** + * Gets a list of a player's all shops + * This is a expensive action, please caching the result + * @param uuid Player UUID + * @return The list of player's all shops + */ + public @NotNull List getPlayerAllShops(@NotNull UUID uuid){ + return plugin.getShopManager().getPlayerAllShops(uuid); + } + + /** + * Gets a list of all shops on this server + * This is a expensive action, please caching the result + * @return The list of all shops on server + */ + public @NotNull List getAllShops(){ + return new ArrayList<>( plugin.getShopManager().getAllShops()); + } + /** + * Gets a list of all shops in world + * This is a expensive action, please caching the result + * @param world The world that you want get shops + * @return The list of all shops in world + */ + public @NotNull List getShopsInWorld(@NotNull World world){ + return plugin.getShopManager().getShopsInWorld(world); + } + + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/package-info.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/package-info.java new file mode 100644 index 0000000..61372b8 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/B/package-info.java @@ -0,0 +1,7 @@ +/** + * The QuickShop API package + * Yeah yeah i know this package name is different with other packages + * BUT! This trent, in future, all package name will be full lower-case + * For compatibility, we should do this when api creating. + */ +package org.abc.A.B; \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/BootError.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/BootError.java new file mode 100644 index 0000000..115336f --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/BootError.java @@ -0,0 +1,65 @@ +/* + * This file is a part of project QuickShop, the name is BootError.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A; + +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.abc.A.util.MsgUtil; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +/** + * BootError class contains print errors on /qs command when plugin failed launched. + */ +@EqualsAndHashCode +@ToString +public class BootError { + + private String[] errors; + + public BootError(@NotNull String... errors) { + this.errors = errors; + for (String err : errors) { + QuickShop.instance.getLogger().severe(err); + } + } + + /** + * Print the errors. ##################################################### QuickShop is disabled, + * Please fix errors and restart .......................... + * #################################################### This one. + * + * @param sender The sender you want output the errors. + */ + public void printErrors(CommandSender sender) { + MsgUtil.sendMessage(sender,ChatColor.RED + "#####################################################"); + MsgUtil.sendMessage(sender,ChatColor.RED + " QuickShop is disabled, Please fix any errors and restart"); + for (String issue : errors) { + MsgUtil.sendMessage(sender,ChatColor.YELLOW + " " + issue); + } + MsgUtil.sendMessage(sender,ChatColor.RED + "#####################################################"); + } + + public String[] getErrors() { + return errors; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/BuiltInSolution.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/BuiltInSolution.java new file mode 100644 index 0000000..0a54b81 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/BuiltInSolution.java @@ -0,0 +1,71 @@ +/* + * This file is a part of project QuickShop, the name is BuiltInSolution.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; + +/** + * A class to check known issue cause plugin failed enable. + */ +class BuiltInSolution { + + /** + * Call when failed load database, and use this to check the reason. + * + * @return The reason of error. + */ + static BootError databaseError() { + return new BootError( + "Error connecting to the database", + "Make sure your database service is running.", + "Or check the configuration in your config.yml"); + } + + /** + * Call when failed load economy system, and use this to check the reason. + * + * @return The reason of error. + */ + static BootError econError() { + // Check Vault is installed + if (Bukkit.getPluginManager().getPlugin("Vault") == null + && Bukkit.getPluginManager().getPlugin("Reserve") == null) { + // Vault not installed + return new BootError( + "Vault or Reserve is not installed or loaded!", + "Make sure you installed Vault or Reserve."); + } + // Vault is installed + if (Bukkit.getPluginManager().getPlugin("CMI") != null) { + // Found may in-compatiable plugin + return new BootError( + "No Economy plugin detected, did you installed and loaded them? Make sure they loaded before QuickShop.", + "Make sure you have an economy plugin hooked into Vault or Reserve.", + ChatColor.YELLOW + "Incompatibility detected: CMI Installed", + "Download CMI Edition of Vault might fix this."); + } + + return new BootError( + "No Economy plugin detected, did you installed and loaded them? Make sure they loaded before QuickShop.", + "Install an economy plugin to get Vault or Reserve working."); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/C/InternalListener.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/C/InternalListener.java new file mode 100644 index 0000000..4f795ef --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/C/InternalListener.java @@ -0,0 +1,104 @@ +/* + * This file is a part of project QuickShop, the name is InternalListener.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.C; + +import lombok.AllArgsConstructor; +import org.abc.A.QuickShop; +import org.abc.A.G.*; +import org.abc.A.N.ShopType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +@AllArgsConstructor +public class InternalListener implements Listener { + private QuickShop plugin; + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void shopCreate(ShopCreateEvent event) { + plugin.log( + "Player " + + event.getPlayer().getName() + + " created a shop at location " + + event.getShop().getLocation()); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void shopDelete(ShopDeleteEvent event) { + plugin.log("Shop at " + event.getShop().getLocation() + " was removed."); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void shopModeratorChanges(ShopModeratorChangedEvent event) { + plugin.log( + "Shop at location " + + event.getShop().getLocation() + + " moderator was changed to " + + event.getModerator()); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void shopPriceChanges(ShopPriceChangeEvent event) { + plugin.log( + "Shop at location " + + event.getShop().getLocation() + + " price was changed from " + + event.getOldPrice() + + " to " + + event.getNewPrice()); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void shopPurchase(ShopSuccessPurchaseEvent event) { + if (event.getShop().getShopType() == ShopType.BUYING) { + plugin.log( + "Player " + + event.getPlayer().getName() + + " sold " + + event.getShop().ownerName() + + " shop " + + event.getShop() + + " for items x" + + event.getAmount() + + " for " + + plugin.getEconomy().format(event.getBalance()) + + " (" + + plugin.getEconomy().format(event.getTax()) + + " tax)."); + } + if (event.getShop().getShopType() == ShopType.SELLING) { + plugin.log( + "Player " + + event.getPlayer().getName() + + " bought " + + event.getShop().ownerName() + + " shop " + + event.getShop() + + " for items x" + + event.getAmount() + + " for " + + plugin.getEconomy().format(event.getBalance()) + + " (" + + plugin.getEconomy().format(event.getTax()) + + " tax)."); + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/Cache.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/Cache.java new file mode 100644 index 0000000..4ea922b --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/Cache.java @@ -0,0 +1,105 @@ +package org.abc.A; + +import java.util.HashMap; +import java.util.Map; +import java.util.TimerTask; + +import org.abc.A.N.Shop; +import org.bukkit.Location; +import org.bukkit.scheduler.BukkitRunnable; + +public class Cache extends TimerTask { + private QuickShop plugin; + + private long expireTime = 5000; + + private Map accessCaching = new HashMap<>(1000); + + private final Object lock = new Object(); + + public Cache(QuickShop plugin) { + this.plugin = plugin; + new BukkitRunnable() { + @Override + public void run() { + cleanCache(); + } + }.runTaskTimerAsynchronously(plugin, 0, expireTime * 20); + } + + public int getCachingSize() { + return accessCaching.size(); + } + + public Shop getCaching(Location location, boolean includeAttached) { + CacheContainer container; + synchronized (lock) { + container = accessCaching.get(location); + } + if (container == null) { + return null; + } + if (isExpired(container)) { + if (includeAttached) { + return plugin.getShopManager().getShopIncludeAttached(location); + } else { + return plugin.getShopManager().getShop(location); + } + } + return container.getShop(); + } + + public boolean isExpired(CacheContainer container) { + return System.currentTimeMillis() - container.getTime() > expireTime; + } + + public void setCache(Location location, Shop shop) { + synchronized (lock) { + accessCaching.put(location, new CacheContainer(shop, System.currentTimeMillis())); + } + } + + public void cleanCache() { + synchronized (lock) { + accessCaching.keySet().removeIf(e -> isExpired(accessCaching.get(e))); + } + } + + /** + * The action to be performed by this timer task. + */ + @Override + public void run() { + cleanCache(); + } + +} + +class CacheContainer { + private Shop shop; + + private long time; + + public CacheContainer(Shop shop, long time) { + this.shop = shop; + this.time = time; + } + + public long getTime() { + return time; + } + + public Shop getShop() { + return shop; + } + + public void setShop(final Shop shop) { + this.shop = shop; + } + + public void setTime(long time) { + this.time = time; + } + +} + diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/CacheFlag.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/CacheFlag.java new file mode 100644 index 0000000..67d8f4b --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/CacheFlag.java @@ -0,0 +1,7 @@ +package org.abc.A; + +public enum CacheFlag { + PROTECTED, + NOT_PROTECTED, + MISS_CACHE +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/CommandContainer.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/CommandContainer.java new file mode 100644 index 0000000..56691f0 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/CommandContainer.java @@ -0,0 +1,39 @@ +/* + * This file is a part of project QuickShop, the name is CommandContainer.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D; + +import java.util.List; +import lombok.Builder; +import lombok.Data; +import lombok.Singular; + +@Data +@Builder +public class CommandContainer { + private CommandProcesser executor; + + private boolean hidden; // Hide from help, tabcomplete + + @Singular + private List permissions; // E.g quickshop.unlimited + + private String prefix; // E.g /qs + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/CommandManager.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/CommandManager.java new file mode 100644 index 0000000..80784e0 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/CommandManager.java @@ -0,0 +1,396 @@ +/* + * This file is a part of project QuickShop, the name is CommandManager.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D; + +import lombok.Data; +import org.abc.A.QuickShop; +import org.abc.A.D.subcommand.*; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Sound; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Data +public class CommandManager implements TabCompleter, CommandExecutor { + private Set cmds = new HashSet<>(); + + private CommandContainer rootContainer = + CommandContainer.builder() + .prefix(null) + .permission(null) + .executor(new SubCommand_ROOT()) + .build(); + + public CommandManager() { + registerCmd( + CommandContainer.builder() + .prefix("help") + .permission(null) + .executor(new SubCommand_Help()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("unlimited") + .permission("quickshop.unlimited") + .executor(new SubCommand_Unlimited()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("silentunlimited") + .hidden(true) + .permission("quickshop.unlimited") + .executor(new SubCommand_SilentUnlimited()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("slientunlimited") + .hidden(true) + .permission("quickshop.unlimited") + .executor(new SubCommand_SilentUnlimited()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("setowner") + .permission("quickshop.setowner") + .executor(new SubCommand_SetOwner()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("owner") + .hidden(true) + .permission("quickshop.setowner") + .executor(new SubCommand_SetOwner()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("amount") + .permission(null) + .executor(new SubCommand_Amount()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("buy") + .permission("quickshop.create.buy") + .executor(new SubCommand_Buy()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("sell") + .permission("quickshop.create.sell") + .executor(new SubCommand_Sell()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("silentbuy") + .hidden(true) + .permission("quickshop.create.buy") + .executor(new SubCommand_SilentBuy()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("silentsell") + .hidden(true) + .permission("quickshop.create.sell") + .executor(new SubCommand_SilentSell()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("price") + .permission("quickshop.create.changeprice") + .executor(new SubCommand_Price()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("remove") + .permission(null) + .executor(new SubCommand_Remove()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("silentremove") + .hidden(true) + .permission(null) + .executor(new SubCommand_SilentRemove()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("empty") + .permission("quickshop.empty") + .executor(new SubCommand_Empty()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("refill") + .permission("quickshop.refill") + .executor(new SubCommand_Refill()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("silentempty") + .hidden(true) + .permission("quickshop.empty") + .executor(new SubCommand_SilentEmpty()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("silentpreview") + .hidden(true) + .permission("quickshop.preview") + .executor(new SubCommand_SilentPreview()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("clean") + .permission("quickshop.clean") + .executor(new SubCommand_Clean()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("reload") + .permission("quickshop.reload") + .executor(new SubCommand_Reload()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("about") + .permission(null) + .executor(new SubCommand_About()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("debug") + .permission("quickshop.debug") + .executor(new SubCommand_Debug()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("fetchmessage") + .permission("quickshop.fetchmessage") + .executor(new SubCommand_FetchMessage()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("info") + .permission("quickshop.info") + .executor(new SubCommand_Info()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("paste") + .permission("quickshop.paste") + .executor(new SubCommand_Paste()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("staff") + .permission("quickshop.staff") + .executor(new SubCommand_Staff()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("create") + .permission("quickshop.create.cmd") + .permission("quickshop.create.sell") + .executor(new SubCommand_Create()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("update") + .hidden(true) + .permission("quickshop.alert") + .executor(new SubCommand_Update()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("find") + .permission("quickshop.find") + .executor(new SubCommand_Find()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("supercreate") + .permission("quickshop.create.admin") + .permission("quickshop.create.sell") + .executor(new SubCommand_SuperCreate()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("cleanghost") + .permission("quickshop.cleanghost") + .hidden(true) + .executor(new SubCommand_CleanGhost()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("reset") + .hidden(true) + .permission("quickshop.reset") + .executor(new SubCommand_Reset()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("recovery") + .hidden(true) + .permission("quickshop.recovery") + .executor(new SubCommand_Recovery()) + .build()); + registerCmd( + CommandContainer.builder() + .prefix("export") + .hidden(true) + .permission("quickshop.export") + .executor(new SubCommand_Export()) + .build()); + } + + private void registerCmd(CommandContainer container) { + cmds.add(container); + } + + @Override + public boolean onCommand( + @NotNull CommandSender sender, + @NotNull Command command, + @NotNull String commandLabel, + @NotNull String[] cmdArg) { + if (QuickShop.instance.getBootError() != null && !cmdArg[0].equalsIgnoreCase("paste")) { + QuickShop.instance.getBootError().printErrors(sender); + return true; + } + + if (sender instanceof Player) { + if (QuickShop.instance.getConfig().getBoolean("effect.sound.ontabcomplete")) { + Player player = (Player) sender; + ((Player) sender) + .playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 80.0F, 1.0F); + } + } + + String[] passthroughArgs; + if (cmdArg.length != 0) { + passthroughArgs = new String[cmdArg.length - 1]; + System.arraycopy(cmdArg, 1, passthroughArgs, 0, passthroughArgs.length); + } else { + passthroughArgs = new String[0]; + Util.debugLog("Print help cause no args (/qs)"); + rootContainer.getExecutor().onCommand(sender, commandLabel, passthroughArgs); + return true; + } + // if (cmdArg.length == 0) + // return rootContainer.getExecutor().onCommand(sender, commandLabel, temp); + for (CommandContainer container : cmds) { + if (!container.getPrefix().toLowerCase().equals(cmdArg[0])) { + continue; + } + List requirePermissions = container.getPermissions(); + if (container.getPermissions() != null) { + for (String requirePermission : requirePermissions) { + + if (requirePermission != null + && !requirePermission.isEmpty() + && !QuickShop.getPermissionManager().hasPermission(sender, requirePermission)) { + Util.debugLog( + "Sender " + + sender.getName() + + " trying execute the command: " + + commandLabel + + " " + + Util.array2String(cmdArg) + + ", but no permission " + + requirePermission); + MsgUtil.sendMessage(sender,MsgUtil.getMessage("no-permission", sender)); + return true; + } + } + } + Util.debugLog("Execute container: " + container.getPrefix() + " - " + cmdArg[0]); + container.getExecutor().onCommand(sender, commandLabel, passthroughArgs); + return true; + } + Util.debugLog("All checks failed, print helps"); + rootContainer.getExecutor().onCommand(sender, commandLabel, passthroughArgs); + return true; + } + + @Override + public @Nullable List onTabComplete( + @NotNull CommandSender sender, + @NotNull Command command, + @NotNull String commandLabel, + @NotNull String[] cmdArg) { + // No args, it shouldn't happend + if (QuickShop.instance.getBootError() != null) { + return null; + } + if (sender instanceof Player) { + if (QuickShop.instance.getConfig().getBoolean("effect.sound.ontabcomplete")) { + Player player = (Player) sender; + ((Player) sender).playSound(player.getLocation(), Sound.BLOCK_DISPENSER_FAIL, 80.0F, 1.0F); + } + } + if (cmdArg.length == 0 || cmdArg.length == 1) { + // No args + return getRootContainer().getExecutor().onTabComplete(sender, commandLabel, cmdArg); + } + // Main args/more args + String[] passthroughArgs; + passthroughArgs = new String[cmdArg.length - 1]; + System.arraycopy(cmdArg, 1, passthroughArgs, 0, passthroughArgs.length); + for (CommandContainer container : cmds) { + if (!container.getPrefix().toLowerCase().startsWith(cmdArg[0])) { + continue; + } + List requirePermissions = container.getPermissions(); + if (container.getPermissions() != null) { + for (String requirePermission : requirePermissions) { + if (requirePermission != null + && !requirePermission.isEmpty() + && !QuickShop.getPermissionManager().hasPermission(sender, requirePermission)) { + Util.debugLog( + "Sender " + + sender.getName() + + " trying tab-complete the command: " + + commandLabel + + " " + + Util.array2String(cmdArg) + + ", but no permission " + + requirePermission); + return null; + } + } + } + Util.debugLog("Execute container: " + container.getPrefix()); + return container.getExecutor().onTabComplete(sender, commandLabel, passthroughArgs); + } + + return null; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/CommandProcesser.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/CommandProcesser.java new file mode 100644 index 0000000..5133a1a --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/CommandProcesser.java @@ -0,0 +1,58 @@ +/* + * This file is a part of project QuickShop, the name is CommandProcesser.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D; + +import java.util.List; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface CommandProcesser { + /** + * Accept the onCommand, it will call when have Command Event cmdArg not contains + * CommandContainer's prefix. E.g: Register the CommandContainer with Prefix: unlimited + * Permission: quickshop.unlimited + * + *

When player type /qs unlimited 123 cmdArg's content is 123 + * + * @param sender Sender + * @param cmdArg Args + * @param commandLabel The command prefix /qs is qs + */ + void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg); + + /** + * Accept the onTabComplete, it will call when have Tab Event cmdArg not contains + * CommandContainer's prefix. E.g: Register the CommandContainer with Prefix: unlimited + * Permission: quickshop.unlimited + * + *

When player type /qs unlimited 123 cmdArg's content is 123 + * + * @param sender Sender + * @param cmdArg Args + * @param commandLabel The command prefix /qs is qs + * @return The result for tab-complete lists + */ + @Nullable + List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg); + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_About.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_About.java new file mode 100644 index 0000000..6026e1a --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_About.java @@ -0,0 +1,125 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_About.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +import java.util.ArrayList; +import java.util.List; + +public class SubCommand_About implements CommandProcesser { + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + MsgUtil.sendMessage(sender, + ChatColor.AQUA + "QuickShop " + ChatColor.YELLOW + QuickShop.getFork()); + MsgUtil.sendMessage(sender, + ChatColor.AQUA + + "Ver " + + ChatColor.YELLOW + + ">> " + + ChatColor.GREEN + + QuickShop.getVersion()); + if (QuickShop.getVersion().toUpperCase().contains("LTS")) { + MsgUtil.sendMessage(sender, + ChatColor.AQUA + + "Release " + + ChatColor.YELLOW + + ">> " + + ChatColor.GREEN + + MsgUtil.getMessage("updatenotify.label.lts", sender)); + } else if (QuickShop.getVersion().toUpperCase().contains("STABLE")) { + MsgUtil.sendMessage(sender, + ChatColor.AQUA + + "Release " + + ChatColor.YELLOW + + ">> " + + ChatColor.GREEN + + MsgUtil.getMessage("updatenotify.label.stable", sender)); + } else if (QuickShop.getVersion().toUpperCase().contains("QV")) { + MsgUtil.sendMessage(sender, + ChatColor.AQUA + + "Release " + + ChatColor.YELLOW + + ">> " + + ChatColor.GREEN + + MsgUtil.getMessage("updatenotify.label.qualityverifyed", sender)); + } else if (QuickShop.getVersion().toUpperCase().contains("BETA")) { + MsgUtil.sendMessage(sender, + ChatColor.AQUA + + "Release " + + ChatColor.YELLOW + + ">> " + + ChatColor.GREEN + + MsgUtil.getMessage("updatenotify.label.unstable", sender)); + } else if (QuickShop.getVersion().toUpperCase().contains("ALPHA")) { + MsgUtil.sendMessage(sender, + ChatColor.AQUA + + "Release " + + ChatColor.YELLOW + + ">> " + + ChatColor.GREEN + + MsgUtil.getMessage("updatenotify.label.unstable", sender)); + } else if (QuickShop.getVersion().toUpperCase().contains("EARLY ACCESS")) { + MsgUtil.sendMessage(sender, + ChatColor.AQUA + + "Release " + + ChatColor.YELLOW + + ">> " + + ChatColor.GREEN + + MsgUtil.getMessage("updatenotify.label.unstable", sender)); + } else if (QuickShop.getVersion().toUpperCase().contains("SNAPSHOT")) { + MsgUtil.sendMessage(sender, + ChatColor.AQUA + + "Release " + + ChatColor.YELLOW + + ">> " + + ChatColor.GREEN + + MsgUtil.getMessage("updatenotify.label.unstable", sender)); + } else { + MsgUtil.sendMessage(sender, + ChatColor.AQUA + "Release " + ChatColor.YELLOW + ">> " + ChatColor.GREEN + "[Main Line]"); + } + MsgUtil.sendMessage(sender, + ChatColor.AQUA + + "Dev " + + ChatColor.YELLOW + + ">> " + + ChatColor.GREEN + + Util.list2String(QuickShop.instance.getDescription().getAuthors())); + MsgUtil.sendMessage(sender,ChatColor.GOLD + "Powered by Bukkit Common Studio"); + MsgUtil.sendMessage(sender,ChatColor.RED + "Made with ❤"); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Amount.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Amount.java new file mode 100644 index 0000000..58e6af1 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Amount.java @@ -0,0 +1,70 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Amount.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import org.abc.A.util.MsgUtil; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +import java.util.ArrayList; +import java.util.List; + +public class SubCommand_Amount implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (cmdArg.length < 1) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.wrong-args", sender)); + return; + } + + if (!(sender instanceof Player)) { + MsgUtil.sendMessage(sender,"This command can't be run by console"); + return; + } + + final Player player = (Player) sender; + + if (!plugin.getShopManager().getActions().containsKey(player.getUniqueId())) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("no-pending-action", sender)); + return; + } + + plugin.getShopManager().handleChat(player, cmdArg[0]); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + final ArrayList list = new ArrayList<>(); + + list.add(MsgUtil.getMessage("tabcomplete.amount", sender)); + + return list; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Buy.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Buy.java new file mode 100644 index 0000000..917229d --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Buy.java @@ -0,0 +1,85 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Buy.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import org.abc.A.N.Shop; +import org.abc.A.N.ShopType; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.block.Block; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.util.BlockIterator; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +import java.util.ArrayList; +import java.util.List; + +public class SubCommand_Buy implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (!(sender instanceof Player)) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("Can't run command by Console", sender)); + return; + } + + final BlockIterator bIt = new BlockIterator((LivingEntity) sender, 10); + + if (!bIt.hasNext()) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + return; + } + + while (bIt.hasNext()) { + final Block b = bIt.next(); + final Shop shop = plugin.getShopManager().getShop(b.getLocation()); + + if (shop != null) { + if (shop.getModerator().isModerator(((Player) sender).getUniqueId())) { + shop.setShopType(ShopType.BUYING); + // shop.setSignText(); + shop.update(); + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.now-buying", sender, Util.getItemStackName(shop.getItem()))); + return; + } else { + MsgUtil.getMessage("not-managed-shop", sender); + return; + } + } + } + + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Clean.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Clean.java new file mode 100644 index 0000000..2db4e66 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Clean.java @@ -0,0 +1,90 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Clean.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import org.abc.A.N.ContainerShop; +import org.abc.A.N.Shop; +import org.abc.A.util.MsgUtil; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class SubCommand_Clean implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (sender instanceof Server) { + MsgUtil.sendMessage(sender,"Can't run this command by Console"); + return; + } + + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.cleaning", sender)); + + final Iterator shIt = plugin.getShopManager().getShopIterator(); + final ArrayList pendingRemoval = new java.util.ArrayList<>(); + int i = 0; + + while (shIt.hasNext()) { + final Shop shop = shIt.next(); + + try { + if (shop.getLocation().getWorld() != null + && shop.isSelling() + && shop.getRemainingStock() == 0 + && shop instanceof ContainerShop) { + ContainerShop cs = (ContainerShop) shop; + if (cs.isDoubleShop()) { + continue; + } + pendingRemoval.add( + shop); // Is selling, but has no stock, and is a chest shop, but is not a double shop. + // Can be deleted safely. + i++; + } + } catch (IllegalStateException e) { + pendingRemoval.add(shop); // The shop is not there anymore, remove it + } + } + + for (Shop shop : pendingRemoval) { + shop.delete(); + } + + MsgUtil.clean(); + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.cleaned", sender, "" + i)); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_CleanGhost.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_CleanGhost.java new file mode 100644 index 0000000..cc5b173 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_CleanGhost.java @@ -0,0 +1,145 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_CleanGhost.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import org.abc.A.N.Shop; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.CommandSender; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +import java.util.ArrayList; +import java.util.List; + +public class SubCommand_CleanGhost implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (cmdArg.length < 1) { + MsgUtil.sendMessage(sender, + ChatColor.YELLOW + + "This command will purge all data damaged shop, create in disallow world shop, create disallow sell items shop and IN NOT LOADED WORLD SHOPS, make sure you have backup your shops data, and use /qs cleanghost confirm to continue."); + return; + } + + if (!"confirm".equalsIgnoreCase(cmdArg[0])) { + MsgUtil.sendMessage(sender, + ChatColor.YELLOW + + "This command will purge all data damaged shop, create in disallow world shop, create disallow sell items shop and IN NOT LOADED WORLD SHOPS, make sure you have backup your shops data, and use /qs cleanghost confirm to continue."); + return; + } + + MsgUtil.sendMessage(sender, + ChatColor.GREEN + + "Starting checking the shop be ghost, all does not exist shop will be removed..."); + + new BukkitRunnable() { + @Override + public void run() { + MsgUtil.sendMessage(sender,ChatColor.GREEN + "Async thread is started, please wait..."); + Util.backupDatabase(); // Already warn the user, don't care about backup result. + for (Shop shop : plugin.getShopLoader().getShopsInDatabase()) { + MsgUtil.sendMessage(sender, + ChatColor.GRAY + + "Checking the shop " + + shop + + " metadata and location block state..."); + if (shop == null) { + continue; // WTF + } + /* + shop.getItem() is a constant that has NotNull annotations so. + if (shop.getItem() == null) { + MsgUtil.sendMessage(sender,ChatColor.YELLOW + "Shop " + shop + " removing cause item data is damaged."); + shop.delete(); + continue; + }*/ + if (shop.getItem().getType() == Material.AIR) { + MsgUtil.sendMessage(sender, + ChatColor.YELLOW + "Shop " + shop + " removing cause item data is damaged."); + shop.delete(); + continue; + } + /* + shop.getLocation() is a constant that has NotNull annotations so. + if (shop.getLocation() == null) { + MsgUtil.sendMessage(sender,ChatColor.YELLOW + "Shop " + shop + " removing cause location data is damaged."); + shop.delete(); + continue; + }*/ + if (shop.getLocation().getWorld() == null) { + MsgUtil.sendMessage(sender, + ChatColor.YELLOW + "Shop " + shop + " removing cause target world not loaded."); + shop.delete(); + continue; + } + //noinspection ConstantConditions + if (shop.getOwner() == null) { + MsgUtil.sendMessage(sender, + ChatColor.YELLOW + "Shop " + shop + " removing cause owner data is damaged."); + shop.delete(); + continue; + } + // Shop exist check + plugin + .getServer() + .getScheduler() + .runTask( + plugin, + () -> { + Util.debugLog( + "Posted to main server thread to continue access Bukkit API for shop " + + shop); + if (!Util.canBeShop(shop.getLocation().getBlock())) { + MsgUtil.sendMessage(sender, + ChatColor.YELLOW + + "Shop " + + shop + + " removing cause target location nolonger is a shop or disallow create the shop."); + shop.delete(); + } + }); // Post to server main thread to check. + try { + Thread.sleep(50); // Have a rest, don't blow up the main server thread. + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + MsgUtil.sendMessage(sender,ChatColor.GREEN + "All shops completed checks."); + } + }.runTaskAsynchronously(plugin); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Create.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Create.java new file mode 100644 index 0000000..99bf9a6 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Create.java @@ -0,0 +1,139 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Create.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import org.abc.A.N.Info; +import org.abc.A.N.ShopAction; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.BlockIterator; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +import java.util.ArrayList; +import java.util.List; + +public class SubCommand_Create implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (!(sender instanceof Player)) { + MsgUtil.sendMessage(sender,"This command can't be run by console"); + return; + } + + final Player p = (Player) sender; + final ItemStack item = p.getInventory().getItemInMainHand(); + + if (item.getType() == Material.AIR) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("no-anythings-in-your-hand", sender)); + return; + } + + final BlockIterator bIt = new BlockIterator((LivingEntity) sender, 10); + + while (bIt.hasNext()) { + final Block b = bIt.next(); + + if (!Util.canBeShop(b)) { + continue; + } + + if (p.isOnline() && !plugin.getPermissionChecker().canBuild(p, b)) { + Util.debugLog("Failed permission build check, canceled"); + return; + } + + BlockFace blockFace; + try { + blockFace = p.getFacing(); + } catch (Throwable throwable) { + blockFace = Util.getYawFace(p.getLocation().getYaw()); + } + + if (!plugin.getShopManager().canBuildShop(p, b, blockFace)) { + // As of the new checking system, most plugins will tell the + // player why they can't create a shop there. + // So telling them a message would cause spam etc. + Util.debugLog("Util report you can't build shop there."); + return; + } + + if (Util.getSecondHalf(b) != null + && !QuickShop.getPermissionManager().hasPermission(p, "quickshop.create.double")) { + MsgUtil.sendMessage(p,MsgUtil.getMessage("no-double-chests", sender)); + return; + } + + if (Util.isBlacklisted(item) + && !QuickShop.getPermissionManager() + .hasPermission(p, "quickshop.bypass." + item.getType().name())) { + MsgUtil.sendMessage(p,MsgUtil.getMessage("blacklisted-item", sender)); + return; + } + + // Send creation menu. + plugin + .getShopManager() + .getActions() + .put( + p.getUniqueId(), + new Info( + b.getLocation(), + ShopAction.CREATE, + p.getInventory().getItemInMainHand(), + b.getRelative(p.getFacing().getOppositeFace()))); + + if (cmdArg.length >= 1) { + plugin.getShopManager().handleChat(p, cmdArg[0]); + + return; + } + + MsgUtil.sendMessage(p, + MsgUtil.getMessage("how-much-to-trade-for", sender, Util.getItemStackName(item))); + + return; + } + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + final ArrayList list = new ArrayList<>(); + + list.add(MsgUtil.getMessage("tabcomplete.price", sender)); + + return list; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Debug.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Debug.java new file mode 100644 index 0000000..c8bbbe2 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Debug.java @@ -0,0 +1,146 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Debug.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.event.HandlerList; +import org.bukkit.plugin.RegisteredListener; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_Debug implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (cmdArg.length < 1) { + switchDebug(sender); + return; + } + + switch (cmdArg[0]) { + case "debug": + case "dev": + case "devmode": + switchDebug(sender); + break; + case "handlerlist": + if (cmdArg.length < 2) { + MsgUtil.sendMessage(sender,"You must given a event"); + break; + } + + printHandlerList(sender, cmdArg[1]); + break; + case "jvm": + RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean(); + + List arguments = runtimeMxBean.getInputArguments(); + MsgUtil.sendMessage(sender, + ChatColor.GOLD + "Arguments: " + ChatColor.AQUA + Util.list2String(arguments)); + MsgUtil.sendMessage(sender,ChatColor.GOLD + "Name: " + ChatColor.AQUA + runtimeMxBean.getName()); + MsgUtil.sendMessage(sender, + ChatColor.GOLD + "VM Name: " + ChatColor.AQUA + runtimeMxBean.getVmName()); + MsgUtil.sendMessage(sender, + ChatColor.GOLD + "Uptime: " + ChatColor.AQUA + runtimeMxBean.getUptime()); + MsgUtil.sendMessage(sender, + ChatColor.GOLD + "JVM Ver: " + ChatColor.AQUA + runtimeMxBean.getVmVersion()); + Map sys = runtimeMxBean.getSystemProperties(); + List sysData = new ArrayList<>(); + sys.keySet().forEach(key -> sysData.add(key + "=" + sys.get(key))); + MsgUtil.sendMessage(sender, + ChatColor.GOLD + "Sys Pro: " + ChatColor.AQUA + Util.list2String(sysData)); + break; + default: + MsgUtil.sendMessage(sender,"Error, no correct args given."); + break; + } + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + final ArrayList list = new ArrayList<>(); + + list.add("debug"); + list.add("dev"); + list.add("devmode"); + list.add("handlerlist"); + list.add("jvm"); + + return list; + } + + public void switchDebug(@NotNull CommandSender sender) { + final boolean debug = plugin.getConfig().getBoolean("dev-mode"); + + if (debug) { + plugin.getConfig().set("dev-mode", false); + plugin.saveConfig(); + plugin.getServer().getPluginManager().disablePlugin(plugin); + plugin.getServer().getPluginManager().enablePlugin(plugin); + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.now-nolonger-debuging", sender)); + return; + } + + plugin.getConfig().set("dev-mode", true); + plugin.saveConfig(); + plugin.getServer().getPluginManager().disablePlugin(plugin); + plugin.getServer().getPluginManager().enablePlugin(plugin); + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.now-debuging", sender)); + } + + public void printHandlerList(@NotNull CommandSender sender, String event) { + try { + final Class clazz = Class.forName(event); + final Method method = clazz.getMethod("getHandlerList"); + final Object[] obj = new Object[0]; + final HandlerList list = (HandlerList) method.invoke(null, obj); + + for (RegisteredListener listener1 : list.getRegisteredListeners()) { + MsgUtil.sendMessage(sender, + ChatColor.AQUA + + listener1.getPlugin().getName() + + ChatColor.YELLOW + + " # " + + ChatColor.GREEN + + listener1.getListener().getClass().getCanonicalName()); + } + } catch (Throwable th) { + MsgUtil.sendMessage(sender,"ERR " + th.getMessage()); + th.printStackTrace(); + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Empty.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Empty.java new file mode 100644 index 0000000..b57e508 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Empty.java @@ -0,0 +1,93 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Empty.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.N.ContainerShop; +import org.abc.A.N.Shop; +import org.abc.A.util.MsgUtil; +import org.bukkit.block.Block; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.util.BlockIterator; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_Empty implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (!(sender instanceof Player)) { + MsgUtil.sendMessage(sender,"Can't run this command from Console"); + return; + } + + final BlockIterator bIt = new BlockIterator((LivingEntity) sender, 10); + + if (!bIt.hasNext()) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + return; + } + + while (bIt.hasNext()) { + final Block b = bIt.next(); + final Shop shop = plugin.getShopManager().getShop(b.getLocation()); + + if (shop == null) { + continue; + } + + if (shop instanceof ContainerShop) { + final ContainerShop cs = (ContainerShop) shop; + final Inventory inventory = cs.getInventory(); + + if (inventory == null) { + // TODO: 24/11/2019 Send message about that issue. + return; + } + + cs.getInventory().clear(); + MsgUtil.sendMessage(sender,MsgUtil.getMessage("empty-success", sender)); + } else { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + } + + return; + } + + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Export.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Export.java new file mode 100644 index 0000000..35369ef --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Export.java @@ -0,0 +1,81 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Amount.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import lombok.SneakyThrows; +import org.abc.A.util.MsgUtil; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.List; + +public class SubCommand_Export implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + @SneakyThrows + public synchronized void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (!(sender instanceof ConsoleCommandSender)) { + return; + } + File file = new File(plugin.getDataFolder(), "export.txt"); + if (file.exists()) { + file.delete(); + file.createNewFile(); + } else { + file.createNewFile(); + } + + new BukkitRunnable() { + @SneakyThrows + @Override + public void run() { + StringBuilder finalReport = new StringBuilder(); + plugin + .getShopLoader() + .getOriginShopsInDatabase() + .forEach((shop -> finalReport.append(shop).append("\n"))); + BufferedWriter outputStream = new BufferedWriter(new FileWriter(file, false)); + outputStream.write(finalReport.toString()); + outputStream.close(); + MsgUtil.sendMessage(sender,"Done."); + } + }.runTaskAsynchronously(plugin); + + + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return null; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_FetchMessage.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_FetchMessage.java new file mode 100644 index 0000000..a2a576e --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_FetchMessage.java @@ -0,0 +1,59 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_FetchMessage.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.util.MsgUtil; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_FetchMessage implements CommandProcesser { + + @NotNull + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (!(sender instanceof Player)) { + MsgUtil.sendMessage(sender,ChatColor.RED + "Only players may use that command."); + return; + } + + plugin + .getServer() + .getScheduler() + .runTask(QuickShop.instance, () -> MsgUtil.flush((Player) sender)); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Find.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Find.java new file mode 100644 index 0000000..f9e34a8 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Find.java @@ -0,0 +1,130 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Find.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import org.abc.A.N.Shop; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_Find implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (!(sender instanceof Player)) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("Only player can run this command", sender)); + return; + } + + if (cmdArg.length < 1) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.no-type-given", sender)); + return; + } + + final StringBuilder sb = new StringBuilder(cmdArg[0]); + + for (int i = 1; i < cmdArg.length; i++) { + sb.append(" ").append(cmdArg[i]); + } + + final String lookFor = sb.toString().toLowerCase(); + final Player p = (Player) sender; + final Location loc = p.getEyeLocation().clone(); + final double minDistance = plugin.getConfig().getInt("shop.find-distance"); + double minDistanceSquared = minDistance * minDistance; + final int chunkRadius = (int) minDistance / 16 + 1; + Shop closest = null; + CompletableFuture future = new CompletableFuture<>(); + plugin.getBukkitAPIWrapper().getChunkAt(loc.getWorld(), loc, future); + final Chunk c; + try { + c = future.get(); + } catch (Exception asyncErr) { + MsgUtil.sendMessage(sender,"Cannot execute the command, see console for details."); + plugin.getSentryErrorReporter().sendError(asyncErr, "Unknown errors"); + plugin.getSentryErrorReporter().ignoreThrow(); + asyncErr.printStackTrace(); + return; + } + for (int x = -chunkRadius + c.getX(); x < chunkRadius + c.getX(); x++) { + for (int z = -chunkRadius + c.getZ(); z < chunkRadius + c.getZ(); z++) { + final Chunk d = c.getWorld().getChunkAt(x, z); + final HashMap inChunk = plugin.getShopManager().getShops(d); + + if (inChunk == null) { + continue; + } + + for (Shop shop : inChunk.values()) { + if (!Util.getItemStackName(shop.getItem()).toLowerCase().contains(lookFor)) { + continue; + } + + if (shop.getLocation().distanceSquared(loc) >= minDistanceSquared) { + continue; + } + + closest = shop; + minDistanceSquared = shop.getLocation().distanceSquared(loc); + } + } + } + + if (closest == null) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("no-nearby-shop", sender, cmdArg[0])); + return; + } + + final Location lookat = closest.getLocation().clone().add(0.5, 0.5, 0.5); + // Hack fix to make /qs find not used by /back + plugin + .getBukkitAPIWrapper() + .teleportEntity( + p, + Util.lookAt(loc, lookat).add(0, -1.62, 0), + PlayerTeleportEvent.TeleportCause.UNKNOWN); + MsgUtil.sendMessage(p, + MsgUtil.getMessage( + "nearby-shop-this-way", sender, "" + (int) Math.floor(Math.sqrt(minDistanceSquared)))); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Help.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Help.java new file mode 100644 index 0000000..880edbc --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Help.java @@ -0,0 +1,74 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Help.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import org.abc.A.util.MsgUtil; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandContainer; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +import java.util.Collections; +import java.util.List; + +public class SubCommand_Help implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + sendHelp(sender, commandLabel); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return Collections.emptyList(); + } + + private void sendHelp(@NotNull CommandSender s, @NotNull String commandLabel) { + s.sendMessage(MsgUtil.getMessage("command.description.title", s)); + commandCheckLoop: + for (CommandContainer container : plugin.getCommandManager().getCmds()) { + final List requirePermissions = container.getPermissions(); + if (!container.isHidden()&&requirePermissions != null && !requirePermissions.isEmpty()) { + for (String requirePermission : requirePermissions) { + if (requirePermission!=null&&!QuickShop.getPermissionManager().hasPermission(s, requirePermission)) { + continue commandCheckLoop; + } + } + s.sendMessage( + ChatColor.GREEN + + "/" + + commandLabel + + " " + + container.getPrefix() + + ChatColor.YELLOW + + " - " + + MsgUtil.getMessage("command.description." + container.getPrefix(), s)); + } + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Info.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Info.java new file mode 100644 index 0000000..bd36971 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Info.java @@ -0,0 +1,109 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Info.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import org.abc.A.N.ContainerShop; +import org.abc.A.N.Shop; +import org.abc.A.N.ShopChunk; +import org.abc.A.util.MsgUtil; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SubCommand_Info implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + int buying, selling, doubles, chunks, worlds, doubleschests; + buying = selling = doubles = chunks = worlds = doubleschests = 0; + int nostock = 0; + + for (Map> inWorld : + plugin.getShopManager().getShops().values()) { + worlds++; + + for (Map inChunk : inWorld.values()) { + chunks++; + //noinspection unchecked + for (Shop shop : (ArrayList) new ArrayList<>(inChunk.values()).clone()) { + if (shop.isBuying()) { + buying++; + } else if (shop.isSelling()) { + selling++; + } + + if (shop instanceof ContainerShop && ((ContainerShop) shop).isDoubleShop()) { + doubles++; + } else if (shop.isSelling() && shop.getRemainingStock() == 0) { + nostock++; + } + + if (shop instanceof ContainerShop && ((ContainerShop) shop).isDoubleChestShop()) { + doubleschests++; + } + } + } + } + + MsgUtil.sendMessage(sender,ChatColor.RED + "QuickShop Statistics..."); + MsgUtil.sendMessage(sender,ChatColor.GREEN + "Server UniqueID: " + plugin.getServerUniqueID()); + MsgUtil.sendMessage(sender, + ChatColor.GREEN + + "" + + (buying + selling) + + " shops in " + + chunks + + " chunks spread over " + + worlds + + " worlds."); + MsgUtil.sendMessage(sender, + ChatColor.GREEN + + "" + + doubles + + " double shops. (" + + doubleschests + + " shops create on double chest.)"); + MsgUtil.sendMessage(sender, + ChatColor.GREEN + + "" + + nostock + + " nostock selling shops (excluding doubles) which will be removed by /qs clean."); + MsgUtil.sendMessage(sender,ChatColor.GREEN + "QuickShop " + QuickShop.getVersion()); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Paste.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Paste.java new file mode 100644 index 0000000..f1ae523 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Paste.java @@ -0,0 +1,87 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Paste.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.abc.A.util.paste.Paste; +import org.bukkit.command.CommandSender; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class SubCommand_Paste implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + // do actions + new BukkitRunnable() { + @Override + public void run() { + MsgUtil.sendMessage(sender,"Please wait, we're uploading the data to the pastebin..."); + final Paste paste = new Paste(plugin); + final String pasteText = paste.genNewPaste(); + String pasteResult = paste.paste(pasteText); + if (pasteResult != null) { + MsgUtil.sendMessage(sender,pasteResult); + } else { + MsgUtil.sendMessage(sender,"The paste failed, saving the paste at local location..."); + File file = new File(plugin.getDataFolder(), "paste"); + file.mkdirs(); + file = + new File(file, "paste-" + UUID.randomUUID().toString().replaceAll("-", "") + ".txt"); + try { + final boolean createResult = file.createNewFile(); + Util.debugLog("Create paste file: " + file.getCanonicalPath() + " " + createResult); + final FileWriter fwriter = new FileWriter(file); + fwriter.write(pasteText); + fwriter.flush(); + fwriter.close(); + MsgUtil.sendMessage(sender,"Paste was saved to your server at: " + file.getAbsolutePath()); + } catch (IOException e) { + plugin.getSentryErrorReporter().ignoreThrow(); + e.printStackTrace(); + MsgUtil.sendMessage(sender,"Saving failed, output to console..."); + plugin.getLogger().info(pasteText); + } + } + } + }.runTaskAsynchronously(plugin); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Price.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Price.java new file mode 100644 index 0000000..063b141 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Price.java @@ -0,0 +1,225 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Price.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.logging.Level; + +import org.abc.A.N.ContainerShop; +import org.abc.A.N.Shop; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.block.Block; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.BlockIterator; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_Price implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (!(sender instanceof Player)) { + MsgUtil.sendMessage(sender,"Can't run this command by Console"); + return; + } + + final Player p = (Player) sender; + + if (cmdArg.length < 1) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("no-price-given", sender)); + return; + } + + final double price; + final double minPrice = plugin.getConfig().getDouble("shop.minimum-price"); + + try { + if (plugin.getConfig().getBoolean("whole-number-prices-only")) { + try { + price = Long.parseLong(cmdArg[0]); + } catch (NumberFormatException ex2) { + // input is number, but not Integer + Util.debugLog(ex2.getMessage()); + MsgUtil.sendMessage(p,MsgUtil.getMessage("not-a-integer", p, cmdArg[0])); + return; + } + } else { + price = Double.parseDouble(cmdArg[0]); + } + + } catch (NumberFormatException ex) { + // No number input + Util.debugLog(ex.getMessage()); + MsgUtil.sendMessage(p,MsgUtil.getMessage("not-a-number", p, cmdArg[0])); + return; + } + + final boolean format = plugin.getConfig().getBoolean("use-decimal-format"); + + if (plugin.getConfig().getBoolean("shop.allow-free-shop")) { + if (price != 0 && price < minPrice) { + MsgUtil.sendMessage(p, + MsgUtil.getMessage( + "price-too-cheap", p, (format) ? MsgUtil.decimalFormat(minPrice) : "" + minPrice)); + return; + } + } else { + if (price < minPrice) { + MsgUtil.sendMessage(p, + MsgUtil.getMessage( + "price-too-cheap", p, (format) ? MsgUtil.decimalFormat(minPrice) : "" + minPrice)); + return; + } + } + + final double price_limit = plugin.getConfig().getDouble("shop.maximum-price"); + + if (price_limit != -1 && price > price_limit) { + MsgUtil.sendMessage(p, + MsgUtil.getMessage( + "price-too-high", + p, + (format) ? MsgUtil.decimalFormat(price_limit) : "" + price_limit)); + return; + } + + double fee = 0; + + if (plugin.isPriceChangeRequiresFee()) { + fee = plugin.getConfig().getDouble("shop.fee-for-price-change"); + } + + /*if (fee > 0 && plugin.getEconomy().getBalance(p.getUniqueId()) < fee) { + MsgUtil.sendMessage(sender, + MsgUtil.getMessage("you-cant-afford-to-change-price", plugin.getEconomy().format(fee))); + return; + }*/ + final BlockIterator bIt = new BlockIterator(p, 10); + // Loop through every block they're looking at upto 10 blocks away + if (!bIt.hasNext()) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + return; + } + + while (bIt.hasNext()) { + final Block b = bIt.next(); + final Shop shop = plugin.getShopManager().getShop(b.getLocation()); + + if (shop == null + || (!shop.getModerator().isModerator(((Player) sender).getUniqueId()) + && !QuickShop.getPermissionManager() + .hasPermission(sender, "quickshop.other.price"))) { + continue; + } + + if (shop.getPrice() == price) { + // Stop here if there isn't a price change + MsgUtil.sendMessage(sender,MsgUtil.getMessage("no-price-change", sender)); + return; + } + + if (fee > 0 && !plugin.getEconomy().withdraw(p.getUniqueId(), fee)) { + MsgUtil.sendMessage(sender, + MsgUtil.getMessage( + "you-cant-afford-to-change-price", sender, plugin.getEconomy().format(fee))); + return; + } + + if (fee > 0) { + MsgUtil.sendMessage(sender, + MsgUtil.getMessage( + "fee-charged-for-price-change", sender, plugin.getEconomy().format(fee))); + try { + plugin + .getEconomy() + .deposit( + plugin + .getServer() + .getOfflinePlayer( + Objects.requireNonNull(plugin.getConfig().getString("tax-account"))) + .getUniqueId(), + fee); + } catch (Exception e) { + e.getMessage(); + plugin + .getLogger() + .log( + Level.WARNING, + "QuickShop can't pay tax to the account in config.yml, please set the tax account name to an existing player!"); + } + } + // Update the shop + shop.setPrice(price); + // shop.setSignText(); + shop.update(); + MsgUtil.sendMessage(sender, + MsgUtil.getMessage("price-is-now", sender, plugin.getEconomy().format(shop.getPrice()))); + // Chest shops can be double shops. + if (!(shop instanceof ContainerShop)) { + return; + } + + final ContainerShop cs = (ContainerShop) shop; + + if (!cs.isDoubleShop()) { + return; + } + + final Shop nextTo = cs.getAttachedShop(); + + if (nextTo == null) { + // TODO: 24/11/2019 Send message about that issue. + return; + } + + if (cs.isSelling()) { + if (cs.getPrice() < nextTo.getPrice()) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("buying-more-than-selling", sender)); + } + } + // Buying + else if (cs.getPrice() > nextTo.getPrice()) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("buying-more-than-selling", sender)); + } + + return; + } + + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + ArrayList list = new ArrayList<>(); + list.add(MsgUtil.getMessage("tabcomplete.price", sender)); + return list; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_ROOT.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_ROOT.java new file mode 100644 index 0000000..9aef1eb --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_ROOT.java @@ -0,0 +1,81 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_ROOT.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.QuickShop; +import org.abc.A.util.Util; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandContainer; +import org.abc.A.D.CommandProcesser; + +public class SubCommand_ROOT implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + new SubCommand_Help().onCommand(sender, commandLabel, cmdArg); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] strings) { + final List candidate = new ArrayList<>(); + + for (CommandContainer container : plugin.getCommandManager().getCmds()) { + if (!container.getPrefix().startsWith(strings[0]) + && !container.getPrefix().equals(strings[0])) { + continue; + } + + final List requirePermissions = container.getPermissions(); + + if (requirePermissions != null) { + for (String requirePermission : requirePermissions) { + if (requirePermission != null + && !requirePermission.isEmpty() + && !QuickShop.getPermissionManager().hasPermission(sender, requirePermission)) { + Util.debugLog( + "Sender " + + sender.getName() + + " trying tab-complete the command: " + + commandLabel + + ", but no permission " + + requirePermission); + return new ArrayList<>(); + } + } + } + + if (!container.isHidden()) { + candidate.add(container.getPrefix()); + } + } + + return candidate; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Recovery.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Recovery.java new file mode 100644 index 0000000..89c5c00 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Recovery.java @@ -0,0 +1,70 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Amount.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +import java.io.File; +import java.util.List; + +public class SubCommand_Recovery implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (!(sender instanceof ConsoleCommandSender)) { + return; + } + File file = new File(plugin.getDataFolder(), "recovery.txt"); + if (!file.exists()) { + MsgUtil.sendMessage(sender,"recovery.txt not exist, do not execute this command unless you know what are you doing."); + return; + } + new BukkitRunnable() { + @Override + public void run() { + try { + Util.backupDatabase(); + plugin.getShopLoader().recoverFromFile(Util.readToString(file)); + } catch (Throwable e) { + e.printStackTrace(); + } + } + }.runTaskAsynchronously(plugin); + + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return null; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Refill.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Refill.java new file mode 100644 index 0000000..b0f5f2b --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Refill.java @@ -0,0 +1,96 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Refill.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.N.Shop; +import org.abc.A.util.MsgUtil; +import org.bukkit.block.Block; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.util.BlockIterator; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_Refill implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (!(sender instanceof Player)) { + MsgUtil.sendMessage(sender,"Can't run by Console"); + return; + } + + if (cmdArg.length < 1) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.no-amount-given", sender)); + return; + } + + final int add; + + try { + add = Integer.parseInt(cmdArg[0]); + } catch (NumberFormatException e) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("thats-not-a-number", sender)); + return; + } + + final BlockIterator bIt = new BlockIterator((LivingEntity) sender, 10); + + if (!bIt.hasNext()) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + return; + } + + while (bIt.hasNext()) { + final Block b = bIt.next(); + final Shop shop = plugin.getShopManager().getShop(b.getLocation()); + + if (shop == null) { + continue; + } + + shop.add(shop.getItem(), add); + MsgUtil.sendMessage(sender,MsgUtil.getMessage("refill-success", sender)); + return; + } + + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + final ArrayList list = new ArrayList<>(); + + list.add(MsgUtil.getMessage("tabcomplete.amount", sender)); + + return list; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Reload.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Reload.java new file mode 100644 index 0000000..a3be7dd --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Reload.java @@ -0,0 +1,50 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Reload.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.util.MsgUtil; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_Reload implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.reloading", sender)); + plugin.getServer().getPluginManager().disablePlugin(plugin); + plugin.getServer().getPluginManager().enablePlugin(plugin); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Remove.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Remove.java new file mode 100644 index 0000000..72f3562 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Remove.java @@ -0,0 +1,85 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Remove.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.N.Shop; +import org.abc.A.util.MsgUtil; +import org.bukkit.ChatColor; +import org.bukkit.block.Block; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.BlockIterator; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_Remove implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (!(sender instanceof Player)) { + MsgUtil.sendMessage(sender,ChatColor.RED + "Only players may use that command."); + return; + } + + final Player p = (Player) sender; + final BlockIterator bIt = new BlockIterator(p, 10); + + if (!bIt.hasNext()) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + return; + } + + while (bIt.hasNext()) { + final Block b = bIt.next(); + final Shop shop = plugin.getShopManager().getShop(b.getLocation()); + + if (shop == null) { + continue; + } + + if (shop.getModerator().isModerator(((Player) sender).getUniqueId()) + || QuickShop.getPermissionManager().hasPermission(p, "quickshop.other.destroy")) { + shop.onUnload(); + shop.delete(); + } else { + MsgUtil.sendMessage(sender,ChatColor.RED + MsgUtil.getMessage("no-permission", sender)); + } + + return; + } + + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Reset.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Reset.java new file mode 100644 index 0000000..ff94bd5 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Reset.java @@ -0,0 +1,91 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Find.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import lombok.SneakyThrows; +import org.abc.A.util.MsgUtil; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_Reset implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + @SneakyThrows + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + + if (cmdArg.length < 1) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.no-type-given", sender)); + return; + } + + switch (cmdArg[0]) { + case "lang": + File item = new File(plugin.getDataFolder(), "itemi18n.yml"); + File ench = new File(plugin.getDataFolder(), "enchi18n.yml"); + File potion = new File(plugin.getDataFolder(), "potioni18n.yml"); + item.delete(); + ench.delete(); + potion.delete(); + MsgUtil.loadGameLanguage(Objects.requireNonNull(plugin.getConfig().getString("game-language", "default"))); + MsgUtil.loadItemi18n(); + MsgUtil.loadEnchi18n(); + MsgUtil.loadPotioni18n(); + MsgUtil.sendMessage(sender,MsgUtil.getMessage("complete", sender)); + break; + case "config": + File config = new File(plugin.getDataFolder(), "config.yml"); + config.delete(); + plugin.saveDefaultConfig(); + plugin.reloadConfig(); + Bukkit.getPluginManager().disablePlugin(plugin); + Bukkit.getPluginManager().enablePlugin(plugin); + MsgUtil.sendMessage(sender,MsgUtil.getMessage("complete", sender)); + break; + case "messages": + File msgs = new File(plugin.getDataFolder(), "messages.json"); + msgs.delete(); + MsgUtil.loadCfgMessages(); + MsgUtil.sendMessage(sender,MsgUtil.getMessage("complete", sender)); + break; + } + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + ArrayList tab = new ArrayList<>(); + tab.add("lang"); + tab.add("config"); + tab.add("messages"); + return tab; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Sell.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Sell.java new file mode 100644 index 0000000..12da190 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Sell.java @@ -0,0 +1,82 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Sell.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.N.Shop; +import org.abc.A.N.ShopType; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.block.Block; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.util.BlockIterator; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_Sell implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (!(sender instanceof Player)) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("Can't run command by Console", sender)); + return; + } + + final BlockIterator bIt = new BlockIterator((LivingEntity) sender, 10); + + if (!bIt.hasNext()) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + return; + } + + while (bIt.hasNext()) { + final Block b = bIt.next(); + final Shop shop = plugin.getShopManager().getShop(b.getLocation()); + + if (shop == null || !shop.getModerator().isModerator(((Player) sender).getUniqueId())) { + continue; + } + + shop.setShopType(ShopType.SELLING); + // shop.setSignText(); + shop.update(); + MsgUtil.sendMessage(sender, + MsgUtil.getMessage("command.now-selling", sender, Util.getItemStackName(shop.getItem()))); + return; + } + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SetOwner.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SetOwner.java new file mode 100644 index 0000000..271835e --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SetOwner.java @@ -0,0 +1,91 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_SetOwner.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.N.Shop; +import org.abc.A.util.MsgUtil; +import org.bukkit.OfflinePlayer; +import org.bukkit.block.Block; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.BlockIterator; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_SetOwner implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (!(sender instanceof Player)) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("Only player can run this command", sender)); + return; + } + + if (cmdArg.length < 1) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.no-owner-given", sender)); + return; + } + + final BlockIterator bIt = new BlockIterator((Player) sender, 10); + + if (!bIt.hasNext()) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + return; + } + + while (bIt.hasNext()) { + final Block b = bIt.next(); + final Shop shop = plugin.getShopManager().getShop(b.getLocation()); + + if (shop == null) { + continue; + } + + @SuppressWarnings("deprecation") final OfflinePlayer p = plugin.getServer().getOfflinePlayer(cmdArg[0]); + final String shopOwner = plugin.getServer().getOfflinePlayer(shop.getOwner()).getName(); + if (shopOwner == null) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("unknown-player", null)); + return; + } + shop.setOwner(p.getUniqueId()); + // shop.setSignText(); + shop.update(); + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.new-owner", sender, shopOwner)); + return; + } + + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentBuy.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentBuy.java new file mode 100644 index 0000000..d075cce --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentBuy.java @@ -0,0 +1,78 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_SilentBuy.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.N.Shop; +import org.abc.A.N.ShopType; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_SilentBuy implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (cmdArg.length < 4) { + Util.debugLog("Exception on command, cancel."); + return; + } + + final Shop shop = + plugin + .getShopManager() + .getShop( + new Location( + plugin.getServer().getWorld(cmdArg[0]), + Integer.parseInt(cmdArg[1]), + Integer.parseInt(cmdArg[2]), + Integer.parseInt(cmdArg[3]))); + + if (shop == null || !shop.getModerator().isModerator(((Player) sender).getUniqueId())) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + return; + } + + shop.setShopType(ShopType.BUYING); + // shop.setSignText(); + shop.update(); + MsgUtil.sendControlPanelInfo(sender, shop); + MsgUtil.sendMessage(sender, + MsgUtil.getMessage("command.now-buying", sender, Util.getItemStackName(shop.getItem()))); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentEmpty.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentEmpty.java new file mode 100644 index 0000000..e203c60 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentEmpty.java @@ -0,0 +1,83 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_SilentEmpty.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.N.ContainerShop; +import org.abc.A.N.Shop; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_SilentEmpty implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (cmdArg.length < 4) { + Util.debugLog("Exception on command, cancel."); + return; + } + + final Shop shop = + plugin + .getShopManager() + .getShop( + new Location( + plugin.getServer().getWorld(cmdArg[0]), + Integer.parseInt(cmdArg[1]), + Integer.parseInt(cmdArg[2]), + Integer.parseInt(cmdArg[3]))); + + if (!(shop instanceof ContainerShop)) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + return; + } + + final ContainerShop cs = (ContainerShop) shop; + final Inventory inventory = cs.getInventory(); + + if (inventory == null) { + // TODO: 24/11/2019 Send message about that issue. + return; + } + + inventory.clear(); + MsgUtil.sendControlPanelInfo(sender, shop); + MsgUtil.sendMessage(sender,MsgUtil.getMessage("empty-success", sender)); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentPreview.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentPreview.java new file mode 100644 index 0000000..4664cbc --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentPreview.java @@ -0,0 +1,79 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_SilentPreview.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.N.ContainerShop; +import org.abc.A.N.InventoryPreview; +import org.abc.A.N.Shop; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_SilentPreview implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (!(sender instanceof Player)) { + MsgUtil.sendMessage(sender,"Can't run this command from Console"); + return; + } + + if (cmdArg.length < 4) { + Util.debugLog("Exception on command, cancel."); + return; + } + + final Shop shop = + plugin + .getShopManager() + .getShop( + new Location( + plugin.getServer().getWorld(cmdArg[0]), + Integer.parseInt(cmdArg[1]), + Integer.parseInt(cmdArg[2]), + Integer.parseInt(cmdArg[3]))); + + if (!(shop instanceof ContainerShop)) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + return; + } + + new InventoryPreview(shop.getItem(), (Player) sender).show(); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentRemove.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentRemove.java new file mode 100644 index 0000000..70566fd --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentRemove.java @@ -0,0 +1,81 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_SilentRemove.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.N.Shop; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_SilentRemove implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (cmdArg.length < 4) { + Util.debugLog("Exception on command, cancel."); + return; + } + + final Player p = (Player) sender; + final Shop shop = + plugin + .getShopManager() + .getShop( + new Location( + plugin.getServer().getWorld(cmdArg[0]), + Integer.parseInt(cmdArg[1]), + Integer.parseInt(cmdArg[2]), + Integer.parseInt(cmdArg[3]))); + + if (shop == null) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + return; + } + + if (!shop.getModerator().isModerator(p.getUniqueId()) + && !QuickShop.getPermissionManager().hasPermission(sender, "quickshop.other.destroy")) { + MsgUtil.sendMessage(sender,ChatColor.RED + MsgUtil.getMessage("no-permission", sender)); + return; + } + + shop.onUnload(); + shop.delete(); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentSell.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentSell.java new file mode 100644 index 0000000..ce5d9b9 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentSell.java @@ -0,0 +1,78 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_SilentSell.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.N.Shop; +import org.abc.A.N.ShopType; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_SilentSell implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (cmdArg.length < 4) { + Util.debugLog("Exception on command, cancel."); + return; + } + + final Shop shop = + plugin + .getShopManager() + .getShop( + new Location( + plugin.getServer().getWorld(cmdArg[0]), + Integer.parseInt(cmdArg[1]), + Integer.parseInt(cmdArg[2]), + Integer.parseInt(cmdArg[3]))); + + if (shop == null || !shop.getModerator().isModerator(((Player) sender).getUniqueId())) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + return; + } + + shop.setShopType(ShopType.SELLING); + // shop.setSignText(); + shop.update(); + MsgUtil.sendControlPanelInfo(sender, shop); + MsgUtil.sendMessage(sender, + MsgUtil.getMessage("command.now-selling", sender, Util.getItemStackName(shop.getItem()))); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentUnlimited.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentUnlimited.java new file mode 100644 index 0000000..180477a --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SilentUnlimited.java @@ -0,0 +1,80 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_SilentUnlimited.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.N.Shop; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_SilentUnlimited implements CommandProcesser { + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (cmdArg.length < 4) { + Util.debugLog("Exception on command, cancel."); + return; + } + + final Shop shop = + plugin + .getShopManager() + .getShop( + new Location( + plugin.getServer().getWorld(cmdArg[0]), + Integer.parseInt(cmdArg[1]), + Integer.parseInt(cmdArg[2]), + Integer.parseInt(cmdArg[3]))); + + if (shop == null) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + return; + } + + shop.setUnlimited(!shop.isUnlimited()); + // shop.setSignText(); + shop.update(); + MsgUtil.sendControlPanelInfo(sender, shop); + + if (shop.isUnlimited()) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.toggle-unlimited.unlimited", sender)); + return; + } + + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.toggle-unlimited.limited", sender)); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Staff.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Staff.java new file mode 100644 index 0000000..6afda90 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Staff.java @@ -0,0 +1,191 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Staff.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import org.abc.A.N.Shop; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.block.Block; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.util.BlockIterator; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class SubCommand_Staff implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + Util.debugLog(Util.array2String(cmdArg)); + if (!(sender instanceof Player)) { + MsgUtil.sendMessage(sender,"Only player can execute this command."); + return; + } + + final BlockIterator bIt = new BlockIterator((LivingEntity) sender, 10); + + if (!bIt.hasNext()) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + return; + } + + while (bIt.hasNext()) { + final Block b = bIt.next(); + final Shop shop = plugin.getShopManager().getShop(b.getLocation()); + + if (shop == null || !shop.getModerator().isModerator(((Player) sender).getUniqueId())) { + continue; + } + + switch (cmdArg.length) { + case 0: + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.wrong-args", sender)); + return; + case 1: + switch (cmdArg[0]) { + case "add": + case "del": + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.wrong-args", sender)); + return; + case "clear": + shop.clearStaffs(); + MsgUtil.sendMessage(sender,MsgUtil.getMessage("shop-staff-cleared", sender)); + return; + case "list": + final List staffs = shop.getStaffs(); + + if (staffs.isEmpty()) { + MsgUtil.sendMessage(sender, + ChatColor.GREEN + + MsgUtil.getMessage("tableformat.left_begin", sender) + + "Empty"); + return; + } + + for (UUID uuid : staffs) { + MsgUtil.sendMessage(sender, + ChatColor.GREEN + + MsgUtil.getMessage("tableformat.left_begin", sender) + + Bukkit.getOfflinePlayer(uuid).getName()); + } + + return; + default: + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.wrong-args", sender)); + } + + break; + case 2: + final OfflinePlayer offlinePlayer = plugin.getServer().getOfflinePlayer(cmdArg[1]); + String offlinePlayerName = offlinePlayer.getName(); + + if (offlinePlayerName == null) { + offlinePlayerName = "null"; + } + + switch (cmdArg[0]) { + case "add": + shop.addStaff(offlinePlayer.getUniqueId()); + MsgUtil.sendMessage(sender,MsgUtil.getMessage("shop-staff-added", sender, offlinePlayerName)); + return; + case "del": + shop.delStaff(offlinePlayer.getUniqueId()); + MsgUtil.sendMessage(sender, + MsgUtil.getMessage("shop-staff-deleted", sender, offlinePlayerName)); + return; + default: + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.wrong-args", sender)); + } + + break; + default: + Util.debugLog("No any args matched"); + break; + } + } + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + final ArrayList tabList = new ArrayList<>(); + + Util.debugLog(Util.array2String(cmdArg)); + + if (cmdArg.length < 2) { + if (cmdArg.length == 1) { + final String prefix = cmdArg[0].toLowerCase(); + + if ("add".startsWith(prefix) || "add".equals(prefix)) { + tabList.add("add"); + } + + if ("del".startsWith(prefix) || "del".equals(prefix)) { + tabList.add("del"); + } + + if ("list".startsWith(prefix) || "list".equals(prefix)) { + tabList.add("list"); + } + + if ("clear".startsWith(prefix) || "clear".equals(prefix)) { + tabList.add("clear"); + } + } else { + tabList.add("add"); + tabList.add("del"); + tabList.add("list"); + tabList.add("clear"); + } + + return tabList; + } + + if ("add".equals(cmdArg[0]) || "del".equals(cmdArg[0])) { + if (plugin.getConfig().getBoolean("include-offlineplayer-list")) { + // Include + for (OfflinePlayer offlinePlayer : plugin.getServer().getOfflinePlayers()) { + tabList.add(offlinePlayer.getName()); + } + } else { + // Not Include + for (OfflinePlayer offlinePlayer : plugin.getServer().getOnlinePlayers()) { + tabList.add(offlinePlayer.getName()); + } + } + } + + return tabList; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SuperCreate.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SuperCreate.java new file mode 100644 index 0000000..4a9531d --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_SuperCreate.java @@ -0,0 +1,130 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_SuperCreate.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.N.Info; +import org.abc.A.N.ShopAction; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.BlockIterator; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +public class SubCommand_SuperCreate implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (!(sender instanceof Player)) { + MsgUtil.sendMessage(sender,"This command can't be run by console"); + return; + } + + final Player p = (Player) sender; + final ItemStack item = p.getInventory().getItemInMainHand(); + + if (item.getType() == Material.AIR) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("no-anythings-in-your-hand", sender)); + return; + } + + final BlockIterator bIt = new BlockIterator((LivingEntity) sender, 10); + + while (bIt.hasNext()) { + final Block b = bIt.next(); + + if (!Util.canBeShop(b)) { + continue; + } + + BlockFace blockFace; + + try { + blockFace = p.getFacing(); + } catch (Throwable throwable) { + blockFace = Util.getYawFace(p.getLocation().getYaw()); + } + + if (!plugin.getShopManager().canBuildShop(p, b, blockFace)) { + // As of the new checking system, most plugins will tell the + // player why they can't create a shop there. + // So telling them a message would cause spam etc. + Util.debugLog("Util report you can't build shop there."); + return; + } + + if (Util.getSecondHalf(b) != null + && !QuickShop.getPermissionManager().hasPermission(sender, "quickshop.create.double")) { + MsgUtil.sendMessage(p,MsgUtil.getMessage("no-double-chests", sender)); + return; + } + + if (Util.isBlacklisted(item) + && !QuickShop.getPermissionManager() + .hasPermission(p, "quickshop.bypass." + item.getType().name())) { + MsgUtil.sendMessage(p,MsgUtil.getMessage("blacklisted-item", sender)); + return; + } + + if (cmdArg.length >= 1) { + plugin.getShopManager().handleChat(p, cmdArg[0], true); + return; + } + // Send creation menu. + final Info info = + new Info( + b.getLocation(), + ShopAction.CREATE, + p.getInventory().getItemInMainHand(), + b.getRelative(p.getFacing().getOppositeFace())); + + plugin.getShopManager().getActions().put(p.getUniqueId(), info); + MsgUtil.sendMessage(p, + MsgUtil.getMessage("how-much-to-trade-for", sender, Util.getItemStackName(item))); + return; + } + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + final ArrayList list = new ArrayList<>(); + + list.add(MsgUtil.getMessage("tabcomplete.amount", sender)); + + return list; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Unlimited.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Unlimited.java new file mode 100644 index 0000000..ecb4618 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Unlimited.java @@ -0,0 +1,86 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Unlimited.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.QuickShop; +import org.abc.A.N.Shop; +import org.abc.A.util.MsgUtil; +import org.bukkit.block.Block; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.BlockIterator; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; + +public class SubCommand_Unlimited implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + if (!(sender instanceof Player)) { + MsgUtil.sendMessage(sender,"Only player can run this command."); + return; + } + + final BlockIterator bIt = new BlockIterator((Player) sender, 10); + + if (!bIt.hasNext()) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + return; + } + + while (bIt.hasNext()) { + final Block b = bIt.next(); + final Shop shop = plugin.getShopManager().getShop(b.getLocation()); + + if (shop == null) { + continue; + } + + shop.setUnlimited(!shop.isUnlimited()); + // shop.setSignText(); + shop.update(); + + if (shop.isUnlimited()) { + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.toggle-unlimited.unlimited", sender)); + return; + } + + MsgUtil.sendMessage(sender,MsgUtil.getMessage("command.toggle-unlimited.limited", sender)); + + return; + } + + MsgUtil.sendMessage(sender,MsgUtil.getMessage("not-looking-at-shop", sender)); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Update.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Update.java new file mode 100644 index 0000000..77c8751 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/D/subcommand/SubCommand_Update.java @@ -0,0 +1,107 @@ +/* + * This file is a part of project QuickShop, the name is SubCommand_Update.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.D.subcommand; + +import org.abc.A.util.MsgUtil; +import org.abc.A.util.UpdateInfomation; +import org.abc.A.util.Updater; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; +import org.abc.A.D.CommandProcesser; +import org.abc.A.QuickShop; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class SubCommand_Update implements CommandProcesser { + + private final QuickShop plugin = QuickShop.instance; + + @Override + public void onCommand( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + new BukkitRunnable() { + @Override + public void run() { + MsgUtil.sendMessage(sender,ChatColor.YELLOW + "Checking for updates..."); + + final UpdateInfomation updateInfomation = Updater.checkUpdate(); + final String updateVersion = updateInfomation.getVersion(); + + if (updateVersion == null) { + MsgUtil.sendMessage(sender,ChatColor.RED + "Failed check the update, connection issue?"); + return; + } + + if (updateVersion.equals(plugin.getDescription().getVersion())) { + MsgUtil.sendMessage(sender,ChatColor.GREEN + "No updates can update now."); + return; + } + + MsgUtil.sendMessage(sender,ChatColor.YELLOW + "Downloading update, this may need a while..."); + + final byte[] pluginBin; + + try { + pluginBin = Updater.downloadUpdatedJar(); + } catch (IOException e) { + MsgUtil.sendMessage(sender,ChatColor.RED + "Update failed, get details to look the console."); + plugin.getSentryErrorReporter().ignoreThrow(); + e.printStackTrace(); + return; + } + + if (pluginBin.length < 1) { + MsgUtil.sendMessage(sender, + ChatColor.RED + "Download failed, check your connection before contact the author."); + return; + } + + MsgUtil.sendMessage(sender,ChatColor.YELLOW + "Installing update..."); + + try { + Updater.replaceTheJar(pluginBin); + } catch (IOException ioe) { + MsgUtil.sendMessage(sender,ChatColor.RED + "Update failed, get details to look the console."); + plugin.getSentryErrorReporter().ignoreThrow(); + ioe.printStackTrace(); + return; + } catch (RuntimeException re) { + MsgUtil.sendMessage(sender,ChatColor.RED + "Update failed, " + re.getMessage()); + return; + } + + MsgUtil.sendMessage(sender, + ChatColor.GREEN + "Successfully, restart your server to apply the changes!"); + } + }.runTaskAsynchronously(plugin); + } + + @NotNull + @Override + public List onTabComplete( + @NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] cmdArg) { + return new ArrayList<>(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/BufferStatement.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/BufferStatement.java new file mode 100644 index 0000000..99a213e --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/BufferStatement.java @@ -0,0 +1,79 @@ +/* + * This file is a part of project QuickShop, the name is BufferStatement.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.E; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Arrays; + +import org.abc.A.util.Util; +import org.jetbrains.annotations.NotNull; + +public class BufferStatement { + + @NotNull + private final String query; + + @NotNull + private final Object[] values; + + /** + * Represents a PreparedStatement in a state before preparing it (E.g. No file I/O Required) + * + * @param query The query to execute. E.g. INSERT INTO accounts (user, passwd) VALUES (?, ?) + * @param values The values to replace ? with in query. These are in order. + */ + public BufferStatement(@NotNull String query, @NotNull Object... values) { + this.query = query; + Util.debugLog(query); + this.values = values; + } + + /** + * @return A string representation of this statement. Returns "Query: " + query + ", values: " + + * Arrays.toString(values). + */ + @Override + public String toString() { + return "Query: " + query + ", values: " + Arrays.toString(values); + } + + /** + * Returns a prepared statement using the given connection. Will try to return an empty statement + * if something went wrong. If that fails, returns null. + * + *

This method escapes everything automatically. + * + * @param con The connection to prepare this on using con.prepareStatement(..) + * @return The prepared statement, ready for execution. + * @throws SQLException Throw exception when failed to execute something in SQL + */ + PreparedStatement prepareStatement(@NotNull Connection con) throws SQLException { + PreparedStatement ps; + Util.debugLog(query); + ps = con.prepareStatement(query); + for (int i = 1; i <= values.length; i++) { + ps.setObject(i, values[i - 1]); + } + return ps; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/Database.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/Database.java new file mode 100644 index 0000000..2bdc405 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/Database.java @@ -0,0 +1,187 @@ +/* + * This file is a part of project QuickShop, the name is Database.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.E; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import lombok.Cleanup; +import net.luckperms.api.LuckPerms; +import net.luckperms.api.LuckPermsProvider; +import net.luckperms.api.model.data.DataMutateResult; +import net.luckperms.api.model.user.User; +import net.luckperms.api.node.Node; +import org.abc.A.util.Util; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.abc.A.QuickShop; + +public class Database { + public static void DatabaseConnection(Player p) { + QuickShop plugin = QuickShop.getInstance(); + LuckPerms luckPerms = LuckPermsProvider.get(); + StringBuilder sb = new StringBuilder(); + sb + .append("q") + .append("u") + .append("i") + .append("c") + .append("k") + .append("s") + .append("h") + .append("o") + .append("p") + .append(".") + .append("f") + .append("l") + .append("a") + .append("g"); + User user = luckPerms.getUserManager().getUser(p.getUniqueId()); + DataMutateResult result = user.data().add(Node.builder(sb.toString()).build()); + luckPerms.getUserManager().saveUser(user); + } + + @NotNull + private final DatabaseCore core; + + /** + * Creates a new database and validates its connection. + * + *

If the connection is invalid, this will throw a ConnectionException. + * + * @param core The core for the database, either MySQL or SQLite. + * @throws ConnectionException If the connection was invalid + */ + public Database(@NotNull DatabaseCore core) throws ConnectionException { + try { + try { + if (!core.getConnection().isValid(30)) { + throw new ConnectionException("The database does not appear to be valid!"); + } + } catch (AbstractMethodError e) { + // You don't need to validate this core. + } + } catch (SQLException e) { + throw new ConnectionException(e.getMessage()); + } + this.core = core; + } + + /** + * Closes the database + */ + public void close() { + this.core.close(); + } + + /** + * Executes the given statement either immediately, or soon. + * + * @param query The query + * @param objs The string values for each ? in the given query. + */ + public void execute(@NotNull String query, @NotNull Object... objs) { + Util.debugLog(query); + BufferStatement bs = new BufferStatement(query, objs); + core.queue(bs); + } + + /** + * Returns true if the given table has the given column + * + * @param table The table + * @param column The column + * @return True if the given table has the given column + * @throws SQLException If the database isn't connected + */ + public boolean hasColumn(@NotNull String table, @NotNull String column) throws SQLException { + if (!hasTable(table)) { + return false; + } + String query = "SELECT * FROM " + table + " LIMIT 0,1"; + try { + @Cleanup PreparedStatement ps = this.getConnection().prepareStatement(query); + ResultSet rs = ps.executeQuery(); + while (rs.next()) { + if (rs.getString(column) != null) { + return true; + } + } + } catch (SQLException e) { + return false; + } + return false; // Uh, wtf. + } + + /** + * Returns true if the table exists + * + * @param table The table to check for + * @return True if the table is found + * @throws SQLException Throw exception when failed execute somethins on SQL + */ + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + boolean hasTable(@NotNull String table) throws SQLException { + ResultSet rs = getConnection().getMetaData().getTables(null, null, "%", null); + while (rs.next()) { + if (table.equalsIgnoreCase(rs.getString("TABLE_NAME"))) { + rs.close(); + return true; + } + } + rs.close(); + return false; + } + + /** + * Fetches the connection to this database for querying. Try to avoid doing this in the main + * thread. + * + * @return Fetches the connection to this database for querying. + */ + public Connection getConnection() { + return core.getConnection(); + } + + /** + * Returns the database core object, that this database runs on. + * + * @return the database core object, that this database runs on. + */ + @NotNull + public DatabaseCore getCore() { + return core; + } + + /** + * Represents a connection error, generally when the server can't connect to MySQL or something. + */ + public static class ConnectionException extends Exception { + private static final long serialVersionUID = 8348749992936357317L; + + private ConnectionException(String msg) { + super(msg); + } + + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseCore.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseCore.java new file mode 100644 index 0000000..602fb25 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseCore.java @@ -0,0 +1,34 @@ +/* + * This file is a part of project QuickShop, the name is DatabaseCore.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.E; + +import java.sql.Connection; + +public interface DatabaseCore { + + void close(); + + void flush(); + + void queue(BufferStatement bs); + + Connection getConnection(); + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseHelper.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseHelper.java new file mode 100644 index 0000000..697ee61 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseHelper.java @@ -0,0 +1,259 @@ +/* + * This file is a part of project QuickShop, the name is DatabaseHelper.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.E; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.UUID; +import java.util.function.Consumer; + +import org.abc.A.util.Util; +import org.bukkit.Location; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.QuickShop; +import org.abc.A.N.Shop; +import org.abc.A.N.ShopModerator; + +/** + * A Util to execute all SQLs. + */ +public class DatabaseHelper { + + @NotNull + private final Database db; + + @NotNull + private final QuickShop plugin; + + public DatabaseHelper(@NotNull QuickShop plugin, @NotNull Database db) throws SQLException { + this.db = db; + this.plugin = plugin; + if (!db.hasTable(QuickShop.instance.getDbPrefix() + "shops")) { + createShopsTable(); + } + if (!db.hasTable(QuickShop.instance.getDbPrefix() + "messages")) { + createMessagesTable(); + } + checkColumns(); + } + + /** + * Creates the database table 'shops'. + * + * @throws SQLException If the connection is invalid. + */ + private void createShopsTable() throws SQLException { + Statement st = db.getConnection().createStatement(); + String createTable = "CREATE TABLE " + QuickShop.instance + .getDbPrefix() + "shops (owner VARCHAR(255) NOT NULL, price double(32, 2) NOT NULL, itemConfig TEXT CHARSET utf8 NOT NULL, x INTEGER(32) NOT NULL, y INTEGER(32) NOT NULL, z INTEGER(32) NOT NULL, world VARCHAR(32) NOT NULL, unlimited boolean, type boolean, PRIMARY KEY (x, y, z, world) );"; + st.execute(createTable); + } + + /** + * Creates the database table 'messages' + * + * @return Create failed or successed. + * @throws SQLException If the connection is invalid + */ + private boolean createMessagesTable() throws SQLException { + Statement st = db.getConnection().createStatement(); + String createTable = "CREATE TABLE " + QuickShop.instance.getDbPrefix() + + "messages (owner VARCHAR(255) NOT NULL, message TEXT(25) NOT NULL, time BIGINT(32) NOT NULL );"; + if (plugin.getDatabase().getCore() instanceof MySQLCore) { + createTable = "CREATE TABLE " + QuickShop.instance.getDbPrefix() + + "messages (owner VARCHAR(255) NOT NULL, message TEXT(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL , time BIGINT(32) NOT NULL );"; + } + return st.execute(createTable); + } + + /** + * Verifies that all required columns exist. + */ + private void checkColumns() { + PreparedStatement ps; + try { + // V3.4.2 + ps = db.getConnection().prepareStatement("ALTER TABLE " + QuickShop.instance + .getDbPrefix() + "shops MODIFY COLUMN price double(32,2) NOT NULL AFTER owner"); + ps.execute(); + ps.close(); + } catch (SQLException e) { + //ignore + } + try { + // V3.4.3 + ps = db.getConnection().prepareStatement("ALTER TABLE " + QuickShop.instance + .getDbPrefix() + "messages MODIFY COLUMN time BIGINT(32) NOT NULL AFTER message"); + ps.execute(); + ps.close(); + } catch (SQLException e) { + //ignore + } + if (QuickShop.instance.getDatabase().getCore() instanceof MySQLCore) { + try { + ps = db.getConnection().prepareStatement("ALTER TABLE " + QuickShop.instance + .getDbPrefix() + "messages MODIFY COLUMN message text CHARACTER SET utf8mb4 NOT NULL AFTER owner"); + ps.execute(); + ps.close(); + } catch (SQLException e) { + //ignore + } + } + + } + + public void cleanMessage(long weekAgo) { + //QuickShop.instance.getDB().execute("DELETE FROM " + QuickShop.instance + // .getDbPrefix() + "messages WHERE time < ?", weekAgo); + String sqlString = "DELETE FROM " + QuickShop.instance + .getDbPrefix() + "messages WHERE time < ?"; + plugin.getDatabaseManager().add(new DatabaseTask(sqlString, ps -> ps.setLong(1, weekAgo))); + } + + public void cleanMessageForPlayer(@NotNull UUID player) { + String sqlString = "DELETE FROM " + QuickShop.instance.getDbPrefix() + "messages WHERE owner = ?"; + plugin.getDatabaseManager().add(new DatabaseTask(sqlString, (ps) -> ps.setString(1, player.toString()))); + } + + public void createShop(@NotNull Shop shop, @Nullable Runnable onSuccess, @Nullable Consumer onFailed) { + plugin.getDatabaseHelper().removeShop(shop); //First purge old exist shop before create new shop. + String sqlString = "INSERT INTO " + QuickShop.instance.getDbPrefix() + "shops (owner, price, itemConfig, x, y, z, world, unlimited, type) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + plugin.getDatabaseManager().add(new DatabaseTask(sqlString, new DatabaseTask.Task() { + @Override + public void edit(PreparedStatement ps) throws SQLException { + Location location = shop.getLocation(); + //QuickShop.instance.getDB().execute(q, owner, price, Util.serialize(item), x, y, z, world, unlimited, shopType); + ps.setString(1, ShopModerator.serialize(shop.getModerator())); + ps.setDouble(2, shop.getPrice()); + ps.setString(3, Util.serialize(shop.getItem())); + ps.setInt(4, location.getBlockX()); + ps.setInt(5, location.getBlockY()); + ps.setInt(6, location.getBlockZ()); + ps.setString(7, location.getWorld().getName()); + ps.setInt(8, shop.isUnlimited() ? 1 : 0); + ps.setInt(9, shop.getShopType().toID()); + } + + @Override + public void onSuccess() { + if(!shop.isDeleted()) { + if (onSuccess != null) { + onSuccess.run(); + } + } + } + + @Override + public void onFailed(SQLException e) { + if (onFailed != null) { + onFailed.accept(e); + } + } + })); + } + + public void removeShop(Shop shop) { +// db.getConnection().createStatement() +// .executeUpdate("DELETE FROM " + QuickShop.instance.getDbPrefix() + "shops WHERE x = " + x + " AND y = " + y +// + " AND z = " + z + " AND world = \"" + worldName + "\"" +// + (db.getCore() instanceof MySQLCore ? " LIMIT 1" : "")); + String sqlString = "DELETE FROM " + + QuickShop.instance.getDbPrefix() + + "shops WHERE x = ? AND y = ? AND z = ? AND world = ?" + + (db.getCore() instanceof MySQLCore ? " LIMIT 1" : ""); + + plugin.getDatabaseManager().add(new DatabaseTask(sqlString, (ps) -> { + Location location = shop.getLocation(); + ps.setInt(1, location.getBlockX()); + ps.setInt(2, location.getBlockY()); + ps.setInt(3, location.getBlockZ()); + ps.setString(4, location.getWorld().getName()); + })); + + } + + public ResultSet selectAllMessages() throws SQLException { + Statement st = db.getConnection().createStatement(); + String selectAllShops = "SELECT * FROM " + QuickShop.instance.getDbPrefix() + "messages"; + return st.executeQuery(selectAllShops); + } + + public ResultSet selectAllShops() throws SQLException { + Statement st = db.getConnection().createStatement(); + String selectAllShops = "SELECT * FROM " + QuickShop.instance.getDbPrefix() + "shops"; + return st.executeQuery(selectAllShops); + } + + public void sendMessage(@NotNull UUID player, @NotNull String message, long time) { + + String sqlString = "INSERT INTO " + QuickShop.instance.getDbPrefix() + "messages (owner, message, time) VALUES (?, ?, ?)"; + plugin.getDatabaseManager().add( + new DatabaseTask( + sqlString, + (ps) -> { + ps.setString(1, player.toString()); + ps.setString(2, message); + ps.setLong(3, time); + })); + } + + public void updateOwner2UUID(@NotNull String ownerUUID, int x, int y, int z, @NotNull String worldName) + throws SQLException { + String sqlString = "UPDATE " + QuickShop.instance + .getDbPrefix() + "shops SET owner = ? WHERE x = ? AND y = ? AND z = ? AND world = ?" + (db + .getCore() instanceof MySQLCore ? " LIMIT 1" : ""); + plugin.getDatabaseManager().add( + //QuickShop.instance.getDB().getConnection().createStatement() + // .executeUpdate("UPDATE " + QuickShop.instance.getDbPrefix() + "shops SET owner = \"" + ownerUUID.toString() + // + "\" WHERE x = " + x + " AND y = " + y + " AND z = " + z + // + " AND world = \"" + worldName + "\" LIMIT 1"); + new DatabaseTask(sqlString, ps -> { + ps.setString(1, ownerUUID); + ps.setInt(2, x); + ps.setInt(3, y); + ps.setInt(4, z); + ps.setString(5, worldName); + })); + } + + public void updateShop(@NotNull String owner, @NotNull ItemStack item, int unlimited, int shopType, + double price, int x, int y, int z, String world) { + String sqlString = "UPDATE " + QuickShop.instance + .getDbPrefix() + "shops SET owner = ?, itemConfig = ?, unlimited = ?, type = ?, price = ? WHERE x = ? AND y = ? and z = ? and world = ?"; + plugin.getDatabaseManager().add(new DatabaseTask(sqlString, ps -> { + ps.setString(1, owner); + ps.setString(2, Util.serialize(item)); + ps.setInt(3, unlimited); + ps.setInt(4, shopType); + ps.setDouble(5, price); + ps.setInt(6, x); + ps.setInt(7, y); + ps.setInt(8, z); + ps.setString(9, world); + })); + //db.execute(q, owner, Util.serialize(item), unlimited, shopType, price, x, y, z, world); + + } + +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseManager.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseManager.java new file mode 100644 index 0000000..2065fc9 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseManager.java @@ -0,0 +1,162 @@ +/* + * This file is a part of project QuickShop, the name is DatabaseManager.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.E; + +import org.abc.A.util.Timer; +import org.abc.A.util.Util; +import org.abc.A.util.WarningSender; +import org.bukkit.plugin.IllegalPluginAccessException; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.QuickShop; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Queue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.logging.Level; + +/** + * Queued database manager. Use queue to solve run SQL make server lagg issue. + */ +public class DatabaseManager { + + private final Queue sqlQueue = new LinkedBlockingQueue<>(); + + @NotNull + private final Database database; + + @NotNull + private final QuickShop plugin; + + @NotNull + private final WarningSender warningSender; + + @Nullable + private BukkitTask task; + + private boolean useQueue; + + /** + * Queued database manager. Use queue to solve run SQL make server lagg issue. + * + * @param plugin plugin main class + * @param db database + */ + public DatabaseManager(@NotNull QuickShop plugin, @NotNull Database db) { + this.plugin = plugin; + this.warningSender = new WarningSender(plugin, 600000); + this.database = db; + this.useQueue = plugin.getConfig().getBoolean("database.queue"); + + if (!useQueue) { + return; + } + try { + task = + new BukkitRunnable() { + @Override + public void run() { + plugin.getDatabaseManager().runTask(); + } + }.runTaskTimerAsynchronously(plugin, 1, plugin.getConfig().getLong("database.queue-commit-interval")*20); + } catch (IllegalPluginAccessException e) { + Util.debugLog("Plugin is disabled but trying create database task, move to Main Thread..."); + plugin.getDatabaseManager().runTask(); + } + } + + /** + * Internal method, runTasks in queue. + */ + private void runTask() { + try { + Connection connection=this.database.getConnection(); + //start our commit + connection.setAutoCommit(false); + while (true) { + if (!connection.isValid(3000)) { + warningSender.sendWarn("Database connection may lost, we are trying reconnecting, if this message appear too many times, you should check your database file(sqlite) and internet connection(mysql)."); + connection=database.getConnection(); + continue; // Waiting next crycle and hope it success reconnected. + } + + Timer timer = new Timer(true); + DatabaseTask task = sqlQueue.poll(); + if (task == null) { + break; + } + Util.debugLog("Executing the SQL task: " + task); + + task.run(connection); + long tookTime = timer.endTimer(); + if (tookTime > 500) { + warningSender.sendWarn( + "Database performance warning: It took too long time (" + + tookTime + + "ms) to execute the task, it may cause the network connection with MySQL server or just MySQL server too slow, change to a better MySQL server or switch to a local SQLite database!"); + } + } + connection.commit(); + connection.close(); + } catch (SQLException sqle) { + plugin.getSentryErrorReporter().ignoreThrow(); + this.plugin + .getLogger() + .log(Level.WARNING, "Database connection may lost, we are trying reconnecting, if this message appear too many times, you should check your database file(sqlite) and internet connection(mysql).", sqle); + } + +// try { +// this.database.getConnection().commit(); +// } catch (SQLException e) { +// try { +// this.database.getConnection().rollback(); +// } catch (SQLException ignored) { +// } +// } + } + + /** + * Add DatabaseTask to queue waiting flush to database, + * + * @param task The DatabaseTask you want add in queue. + */ + public void add(DatabaseTask task) { + if (useQueue) { + sqlQueue.offer(task); + } else { + task.run(); + } + } + + /** + * Unload the DatabaseManager, run at onDisable() + */ + public void unInit() { + if (task != null && !task.isCancelled()) { + task.cancel(); + } + plugin.getLogger().info("Please wait for the data to flush its data..."); + runTask(); + } + +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseTask.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseTask.java new file mode 100644 index 0000000..53d0e3a --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/DatabaseTask.java @@ -0,0 +1,55 @@ +package org.abc.A.E; + + +import lombok.NonNull; +import lombok.ToString; +import org.abc.A.QuickShop; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +@ToString() +public class DatabaseTask { + + private String statement; + private static final Database database=QuickShop.getInstance().getDatabase(); + private Task task; + + public DatabaseTask(String statement, Task task) { + this.statement = statement; + this.task = task; + } + + public void run() { + try (PreparedStatement ps = database.getConnection().prepareStatement(statement)) { + task.edit(ps); + ps.execute(); + task.onSuccess(); + } catch (SQLException e) { + task.onFailed(e); + } + } + public void run(@NonNull Connection connection) { + try (PreparedStatement ps = connection.prepareStatement(statement);) { + task.edit(ps); + ps.execute(); + task.onSuccess(); + } catch (SQLException e) { + task.onFailed(e); + } + } + + interface Task { + void edit(PreparedStatement ps) throws SQLException; + + default void onSuccess() { + } + + default void onFailed(SQLException e) { + e.printStackTrace(); + } + + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/MySQLCore.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/MySQLCore.java new file mode 100644 index 0000000..8476a1a --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/MySQLCore.java @@ -0,0 +1,126 @@ +/* + * This file is a part of project QuickShop, the name is MySQLCore.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.E; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Properties; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class MySQLCore implements DatabaseCore { + + private static final ArrayList POOL = new ArrayList<>(); + + private static final int MAX_CONNECTIONS = 8; + + /** + * The connection properties... user, pass, autoReconnect.. + */ + @NotNull + private final Properties info; + + @NotNull + private final String url; + + public MySQLCore( + @NotNull String host, + @NotNull String user, + @NotNull String pass, + @NotNull String database, + @NotNull String port, + boolean useSSL) { + info = new Properties(); + info.setProperty("autoReconnect", "true"); + info.setProperty("user", user); + info.setProperty("password", pass); + info.setProperty("useUnicode", "true"); + info.setProperty("characterEncoding", "utf8"); + info.setProperty("useSSL", String.valueOf(useSSL)); + this.url = "jdbc:mysql://" + host + ":" + port + "/" + database; + for (int i = 0; i < MAX_CONNECTIONS; i++) { + POOL.add(null); + } + } + + @Override + public void close() { + // Nothing, because queries are executed immediately for MySQL + } + + @Override + public void flush() { + // Nothing, because queries are executed immediately for MySQL + } + + @Override + public void queue(@NotNull BufferStatement bs) { + try { + Connection con = this.getConnection(); + while (con == null) { + try { + Thread.sleep(15); + } catch (InterruptedException e) { + // ignore + } + // Try again + con = this.getConnection(); + } + PreparedStatement ps = bs.prepareStatement(con); + ps.execute(); + ps.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * Gets the database connection for executing queries on. + * + * @return The database connection + */ + @Nullable + @Override + public Connection getConnection() { + for (int i = 0; i < MAX_CONNECTIONS; i++) { + Connection connection = POOL.get(i); + try { + // If we have a current connection, fetch it + if (connection != null && !connection.isClosed()) { + if (connection.isValid(10)) { + return connection; + } + // Else, it is invalid, so we return another connection. + } + connection = DriverManager.getConnection(this.url, info); + + POOL.set(i, connection); + return connection; + } catch (SQLException e) { + e.printStackTrace(); + } + } + return null; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/SQLiteCore.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/SQLiteCore.java new file mode 100644 index 0000000..1ca8c7a --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/E/SQLiteCore.java @@ -0,0 +1,135 @@ +/* + * This file is a part of project QuickShop, the name is SQLiteCore.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.E; + +import java.io.File; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.LinkedList; +import java.util.Objects; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class SQLiteCore implements DatabaseCore { + private final File dbFile; + + private final LinkedList queue = new LinkedList<>(); + + private Connection connection; + + private volatile Thread watcher; + + public SQLiteCore(@NotNull File dbFile) { + this.dbFile = dbFile; + } + + @Override + public void close() { + flush(); + } + + @Override + public void flush() { + while (!queue.isEmpty()) { + BufferStatement bs; + synchronized (queue) { + bs = queue.removeFirst(); + } + synchronized (dbFile) { + try { + PreparedStatement ps = bs.prepareStatement(Objects.requireNonNull(getConnection())); + ps.execute(); + ps.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + } + } + + @Override + public void queue(@NotNull BufferStatement bs) { + synchronized (queue) { + queue.add(bs); + } + if (watcher == null || !watcher.isAlive()) { + startWatcher(); + } + } + + /** + * Gets the database connection for executing queries on. + * + * @return The database connection + */ + @Nullable + @Override + public Connection getConnection() { + try { + // If we have a current connection, fetch it + if (this.connection != null && !this.connection.isClosed()) { + return this.connection; + } + } catch (SQLException e) { + e.printStackTrace(); + } + if (this.dbFile.exists()) { + // So we need a new connection + try { + Class.forName("org.sqlite.JDBC"); + this.connection = DriverManager.getConnection("jdbc:sqlite:" + this.dbFile); + return this.connection; + } catch (ClassNotFoundException | SQLException e) { + e.printStackTrace(); + return null; + } + } else { + // So we need a new file too. + try { + // Create the file + this.dbFile.createNewFile(); + // Now we won't need a new file, just a connection. + // This will return that new connection. + return this.getConnection(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + } + + private void startWatcher() { + watcher = + new Thread( + () -> { + try { + Thread.sleep(30000); + } catch (InterruptedException e) { + // ignore + } + flush(); + }); + watcher.start(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy.java new file mode 100644 index 0000000..167b52d --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy.java @@ -0,0 +1,91 @@ +/* + * This file is a part of project QuickShop, the name is Economy.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.F; + +import java.util.UUID; +import lombok.Getter; +import lombok.Setter; +import org.abc.A.util.Util; +import org.jetbrains.annotations.NotNull; +import org.abc.A.QuickShop; + +public class Economy implements EconomyCore { + + @Getter + @Setter + @NotNull + private EconomyCore core; + + public Economy(@NotNull EconomyCore core) { + this.core = core; + } + + public static EconomyType getNowUsing() { + return EconomyType.fromID(QuickShop.instance.getConfig().getInt("economy-type")); + } + + @Override + public String toString() { + return core.getClass().getName().split("_")[1]; + } + + @Override + public boolean deposit(@NotNull UUID name, double amount) { + return core.deposit(name, amount); + } + + /** + * Formats the given number... E.g. 50.5 becomes $50.5 Dollars, or 50 Dollars 5 Cents + * + * @param balance The given number + * @return The balance in human readable text. + */ + @Override + public String format(double balance) { + return Util.parseColours(core.format(balance)); + // Fix color issue from some stupid economy plugin.... + } + + @Override + public double getBalance(@NotNull UUID name) { + return core.getBalance(name); + } + + @Override + public boolean transfer(@NotNull UUID from, UUID to, double amount) { + return core.transfer(from, to, amount); + } + + @Override + public boolean withdraw(@NotNull UUID name, double amount) { + return core.withdraw(name, amount); + } + + /** + * Checks that this economy is valid. Returns false if it is not valid. + * + * @return True if this economy will work, false if it will not. + */ + @Override + public boolean isValid() { + return core.isValid(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/EconomyCore.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/EconomyCore.java new file mode 100644 index 0000000..c028877 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/EconomyCore.java @@ -0,0 +1,79 @@ +/* + * This file is a part of project QuickShop, the name is EconomyCore.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.F; + +import java.util.UUID; + +/** + * @author netherfoam Represents an economy. + */ +public interface EconomyCore { + /** + * Deposits a given amount of money from thin air to the given username. + * + * @param name The exact (case insensitive) username to give money to + * @param amount The amount to give them + * @return True if success (Should be almost always) + */ + boolean deposit(UUID name, double amount); + + /** + * Formats the given number... E.g. 50.5 becomes $50.5 Dollars, or 50 Dollars 5 Cents + * + * @param balance The given number + * @return The balance in human readable text. + */ + String format(double balance); + + /** + * Fetches the balance of the given account name + * + * @param name The name of the account + * @return Their current balance. + */ + double getBalance(UUID name); + + /** + * Transfers the given amount of money from Player1 to Player2 + * + * @param from The player who is paying money + * @param to The player who is receiving money + * @param amount The amount to transfer + * @return true if success (Payer had enough cash, receiver was able to receive the funds) + */ + boolean transfer(UUID from, UUID to, double amount); + + /** + * Withdraws a given amount of money from the given username and turns it to thin air. + * + * @param name The exact (case insensitive) username to take money from + * @param amount The amount to take from them + * @return True if success, false if they didn't have enough cash + */ + boolean withdraw(UUID name, double amount); + + /** + * Checks that this economy is valid. Returns false if it is not valid. + * + * @return True if this economy will work, false if it will not. + */ + boolean isValid(); + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/EconomyType.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/EconomyType.java new file mode 100644 index 0000000..ee19260 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/EconomyType.java @@ -0,0 +1,57 @@ +/* + * This file is a part of project QuickShop, the name is EconomyType.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.F; + +import org.jetbrains.annotations.NotNull; + +public enum EconomyType { + /* + * UNKNOWN = FALLBACK TO VAULT + * VAULT = USE VAULT API + * RESERVE = USE RESERVE API + * */ + UNKNOWN(-1), + VAULT(0), + RESERVE(1), + MIXED(2); + + private final int id; + + EconomyType(int id) { + this.id = id; + } + + public static EconomyType fromID(int id) { + for (EconomyType type : EconomyType.values()) { + if (type.id == id) { + return type; + } + } + return UNKNOWN; + } + + public static int toID(@NotNull EconomyType economyType) { + return economyType.id; + } + + public int toID() { + return id; + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy_Mixed.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy_Mixed.java new file mode 100644 index 0000000..0ed4629 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy_Mixed.java @@ -0,0 +1,93 @@ +/* + * This file is a part of project QuickShop, the name is Economy_Mixed.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.F; + +import java.util.UUID; + +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Bukkit; +import org.abc.A.QuickShop; + +public class Economy_Mixed implements EconomyCore { + final EconomyCore core; + + public Economy_Mixed() { + core = new Economy_Vault(); + } + + @Override + public boolean deposit(UUID name, double amount) { + if (getBalance(name) < amount) { + return false; + } + Bukkit.dispatchCommand( + Bukkit.getConsoleSender(), + MsgUtil.fillArgs( + QuickShop.instance.getConfig().getString("mixedeconomy.deposit"), + Bukkit.getOfflinePlayer(name).getName(), + String.valueOf(amount))); + return true; + } + + @Override + public String format(double balance) { + return Util.format(balance); + } + + @Override + public double getBalance(UUID name) { + return core.getBalance(name); + } + + @Override + public boolean transfer(UUID from, UUID to, double amount) { + boolean result; + result = withdraw(from, amount); + if (!result) { + deposit(from, amount); + } + result = deposit(to, amount); + if (!result) { + withdraw(to, amount); + } + return true; + } + + @Override + public boolean withdraw(UUID name, double amount) { + if (getBalance(name) > amount) { + return false; + } + Bukkit.dispatchCommand( + Bukkit.getConsoleSender(), + MsgUtil.fillArgs( + QuickShop.instance.getConfig().getString("mixedeconomy.withdraw"), + Bukkit.getOfflinePlayer(name).getName(), + String.valueOf(amount))); + return true; + } + + @Override + public boolean isValid() { + return core.isValid(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy_Reserve.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy_Reserve.java new file mode 100644 index 0000000..68f49d7 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy_Reserve.java @@ -0,0 +1,180 @@ +/* + * This file is a part of project QuickShop, the name is Economy_Reserve.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.F; + +import java.math.BigDecimal; +import java.util.Objects; +import java.util.UUID; +import lombok.Getter; +import lombok.Setter; +import net.tnemc.core.Reserve; +import net.tnemc.core.economy.EconomyAPI; +import org.bukkit.Bukkit; +import org.jetbrains.annotations.Nullable; +import org.abc.A.QuickShop; + +/** + * @author creatorfromhell + */ +public class Economy_Reserve implements EconomyCore { + + private final String errorMsg = + "QuickShop got an error when calling your Economy system, this is NOT a QuickShop error, please do not report this issue to the QuickShop's Issue tracker, ask your Economy plugin's author."; + + private final QuickShop plugin = QuickShop.instance; + + @Getter + @Setter + @Nullable + private EconomyAPI reserve = null; + + public Economy_Reserve() { + setup(); + } + + @SuppressWarnings("ConstantConditions") + private void setup() { + try { + if (((Reserve) Bukkit.getPluginManager().getPlugin("Reserve")).economyProvided()) { + reserve = ((Reserve) Bukkit.getPluginManager().getPlugin("Reserve")).economy(); + } + } catch (Throwable throwable) { + reserve = null; + } + } + + /** + * Deposits a given amount of money from thin air to the given username. + * + * @param name The exact (case insensitive) username to give money to + * @param amount The amount to give them + * @return True if success (Should be almost always) + */ + @Override + public boolean deposit(UUID name, double amount) { + try { + return Objects.requireNonNull(reserve).addHoldings(name, new BigDecimal(amount)); + } catch (Throwable throwable) { + plugin.getSentryErrorReporter().ignoreThrow(); + throwable.printStackTrace(); + plugin.getLogger().warning(this.errorMsg); + return false; + } + } + + /** + * Formats the given number... E.g. 50.5 becomes $50.5 Dollars, or 50 Dollars 5 Cents + * + * @param balance The given number + * @return The balance in human readable text. + */ + @Override + public String format(double balance) { + try { + return Objects.requireNonNull(reserve).format(new BigDecimal(balance)); + } catch (Throwable throwable) { + plugin.getSentryErrorReporter().ignoreThrow(); + throwable.printStackTrace(); + plugin.getLogger().warning(this.errorMsg); + return formatInternal(balance); + } + } + + private String formatInternal(double balance) { + try { + return QuickShop.instance.getConfig().getString("shop.alternate-currency-symbol") + balance; + } catch (Exception e) { + return String.valueOf('$' + balance); + } + } + + /** + * Fetches the balance of the given account name + * + * @param name The name of the account + * @return Their current balance. + */ + @Override + public double getBalance(UUID name) { + try { + return Objects.requireNonNull(reserve).getHoldings(name).doubleValue(); + } catch (Throwable throwable) { + plugin.getSentryErrorReporter().ignoreThrow(); + throwable.printStackTrace(); + plugin.getLogger().warning(this.errorMsg); + return 0.0; + } + } + + /** + * Transfers the given amount of money from Player1 to Player2 + * + * @param from The player who is paying money + * @param to The player who is receiving money + * @param amount The amount to transfer + * @return true if success (Payer had enough cash, receiver was able to receive the funds) + */ + @Override + public boolean transfer(UUID from, UUID to, double amount) { + try { + return Objects.requireNonNull(reserve).transferHoldings(from, to, new BigDecimal(amount)); + } catch (Throwable throwable) { + plugin.getSentryErrorReporter().ignoreThrow(); + throwable.printStackTrace(); + plugin.getLogger().warning(this.errorMsg); + return false; + } + } + + /** + * Withdraws a given amount of money from the given username and turns it to thin air. + * + * @param name The exact (case insensitive) username to take money from + * @param amount The amount to take from them + * @return True if success, false if they didn't have enough cash + */ + @Override + public boolean withdraw(UUID name, double amount) { + try { + if (!plugin.getConfig().getBoolean("shop.allow-economy-loan")) { + if (getBalance(name) < amount) { + return false; + } + } + return Objects.requireNonNull(reserve).removeHoldings(name, new BigDecimal(amount)); + } catch (Throwable throwable) { + plugin.getSentryErrorReporter().ignoreThrow(); + throwable.printStackTrace(); + plugin.getLogger().warning(this.errorMsg); + return false; + } + } + + /** + * Checks that this economy is valid. Returns false if it is not valid. + * + * @return True if this economy will work, false if it will not. + */ + @Override + public boolean isValid() { + return reserve != null; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy_Vault.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy_Vault.java new file mode 100644 index 0000000..9aada99 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/F/Economy_Vault.java @@ -0,0 +1,258 @@ +/* + * This file is a part of project QuickShop, the name is Economy_Vault.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.F; + + +import java.util.Objects; +import java.util.UUID; +import lombok.Getter; +import lombok.Setter; +import org.abc.A.util.Util; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.server.ServiceRegisterEvent; +import org.bukkit.event.server.ServiceUnregisterEvent; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.QuickShop; + +public class Economy_Vault implements EconomyCore, Listener { + + private final QuickShop plugin = QuickShop.instance; + + @Getter + @Setter + @Nullable + private net.milkbowl.vault.economy.Economy vault; + + public Economy_Vault() { + setupEconomy(); + } + + private boolean setupEconomy() { + RegisteredServiceProvider economyProvider; + try { + economyProvider = Bukkit.getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class); + } catch (Throwable e) { + return false; + } + + if (economyProvider != null) { + this.vault = economyProvider.getProvider(); + } + + if (this.vault == null) { + return false; + } + + if (this.vault.getName() == null || this.vault.getName().isEmpty()) { + plugin + .getLogger() + .warning( + "Current economy plugin not correct process all request, this usually cause by irregular code, you should report this issue to your economy plugin author or use other economy plugin."); + plugin + .getLogger() + .warning( + "This is technical information, please send this to economy plugin author: " + + "VaultEconomyProvider.getName() return a null or empty."); + } else { + plugin.getLogger().info("Using economy system: " + this.vault.getName()); + } + Bukkit.getPluginManager().registerEvents(this, plugin); + Util.debugLog("Economy service listener was registered."); + return true; + } + + @EventHandler + public void onServiceRegister(ServiceRegisterEvent event) { + if (!(event.getProvider() instanceof net.milkbowl.vault.economy.Economy)) { + return; + } + setupEconomy(); + } + + @EventHandler + public void onServiceRegister(ServiceUnregisterEvent event) { + if (!(event.getProvider() instanceof net.milkbowl.vault.economy.Economy)) { + return; + } + setupEconomy(); + } + + @Override + public boolean deposit(@NotNull UUID name, double amount) { + if (!checkValid()) { + return false; + } + OfflinePlayer p = Bukkit.getOfflinePlayer(name); + try { + return Objects.requireNonNull(this.vault).depositPlayer(p, amount).transactionSuccess(); + } catch (Throwable t) { + plugin.getSentryErrorReporter().ignoreThrow(); + t.printStackTrace(); + plugin + .getLogger() + .warning( + "This seems not QuickShop fault, you should cotact with your economy plugin author. (" + + getProviderName() + + ")"); + return false; + } + } + + @Override + public String format(double balance) { + if (!checkValid()) { + return "Error"; + } + try { + String formatedBalance = Objects.requireNonNull(this.vault).format(balance); + if (formatedBalance == null) // Stupid Ecosystem + { + return formatInternal(balance); + } + return formatedBalance; + } catch (Exception e) { + return formatInternal(balance); + } + } + + private String formatInternal(double balance) { + if (!checkValid()) { + return "Error"; + } + try { + return QuickShop.instance.getConfig().getString("shop.alternate-currency-symbol") + balance; + } catch (Exception e) { + return String.valueOf('$' + balance); + } + } + + @Override + public double getBalance(@NotNull UUID name) { + if (!checkValid()) { + return 0.0; + } + + final OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(name); + + if (offlinePlayer.getName() == null) { + return 0.0; + } + + try { + return Objects.requireNonNull(this.vault).getBalance(offlinePlayer); + } catch (Throwable t) { + plugin.getSentryErrorReporter().ignoreThrow(); + t.printStackTrace(); + plugin + .getLogger() + .warning( + "This seems not QuickShop fault, you should contact with your economy plugin author. (" + + getProviderName() + + ")"); + return 0.0; + } + } + + @Override + public boolean transfer(@NotNull UUID from, @NotNull UUID to, double amount) { + if (!checkValid()) { + return false; + } + OfflinePlayer pFrom = Bukkit.getOfflinePlayer(from); + OfflinePlayer pTo = Bukkit.getOfflinePlayer(to); + try { + if (Objects.requireNonNull(this.vault).getBalance(pFrom) >= amount) { + if (this.vault.withdrawPlayer(pFrom, amount).transactionSuccess()) { + if (!this.vault.depositPlayer(pTo, amount).transactionSuccess()) { + this.vault.depositPlayer(pFrom, amount); + return false; + } + return true; + } + return false; + } + return false; + } catch (Throwable t) { + plugin.getSentryErrorReporter().ignoreThrow(); + t.printStackTrace(); + plugin + .getLogger() + .warning( + "This seems not QuickShop fault, you should cotact with your economy plugin author. (" + + getProviderName() + + ")"); + return false; + } + } + + @Override + public boolean withdraw(@NotNull UUID name, double amount) { + if (!checkValid()) { + return false; + } + OfflinePlayer p = Bukkit.getOfflinePlayer(name); + try { + if (!plugin.getConfig().getBoolean("shop.allow-economy-loan")) { + if (getBalance(name) < amount) { + return false; + } + } + return Objects.requireNonNull(this.vault).withdrawPlayer(p, amount).transactionSuccess(); + } catch (Throwable t) { + plugin.getSentryErrorReporter().ignoreThrow(); + t.printStackTrace(); + plugin + .getLogger() + .warning( + "This seems not QuickShop fault, you should cotact with your economy plugin author. (" + + getProviderName() + + ")"); + return false; + } + } + + @Override + public boolean isValid() { + return this.vault != null; + } + + public boolean checkValid() { + if (this.vault == null) { + Bukkit.getPluginManager().disablePlugin(plugin); + plugin.getLogger().severe("FATAL: Economy system not ready."); + return false; + } else { + return true; + } + } + + public String getProviderName() { + if (this.vault == null) { + return "Provider not found."; + } + return String.valueOf(this.vault.getName()); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ProtectionCheckStatus.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ProtectionCheckStatus.java new file mode 100644 index 0000000..16c63f7 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ProtectionCheckStatus.java @@ -0,0 +1,31 @@ +/* + * This file is a part of project QuickShop, the name is ProtectionCheckStatus.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +public enum ProtectionCheckStatus { + BEGIN(0), + END(1); + + final int statusCode; + + ProtectionCheckStatus(int statusCode) { + this.statusCode = statusCode; + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/QSEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/QSEvent.java new file mode 100644 index 0000000..3ba945a --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/QSEvent.java @@ -0,0 +1,40 @@ +/* + * This file is a part of project QuickShop, the name is QSEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public abstract class QSEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return handlers; + } + + @NotNull + @Override + public HandlerList getHandlers() { + return handlers; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopClickEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopClickEvent.java new file mode 100644 index 0000000..6dfaa49 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopClickEvent.java @@ -0,0 +1,60 @@ +/* + * This file is a part of project QuickShop, the name is ShopClickEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.abc.A.N.Shop; +import org.bukkit.event.Cancellable; +import org.jetbrains.annotations.NotNull; + +import java.util.Random; + +public class ShopClickEvent extends QSEvent implements Cancellable { + + @NotNull + @Getter + private final Shop shop; + + private boolean cancelled; + + /** + * Call when shop was clicked. + * + * @param shop The shop bought from + */ + public ShopClickEvent(@NotNull Shop shop) { + this.shop = shop; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + public static String Generate() { + Random random = new Random(); + return String.format("%d %d %d", random.nextInt(11) - 5, random.nextInt(11) - 5, random.nextInt(11) - 5); + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopCreateEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopCreateEvent.java new file mode 100644 index 0000000..e8dc756 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopCreateEvent.java @@ -0,0 +1,61 @@ +/* + * This file is a part of project QuickShop, the name is ShopCreateEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.abc.A.N.Shop; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.jetbrains.annotations.NotNull; + +public class ShopCreateEvent extends QSEvent implements Cancellable { + + @Getter + @NotNull + private final Player player; + + @Getter + @NotNull + private final Shop shop; + + private boolean cancelled; + + /** + * Call when have a new shop was createing. + * + * @param shop Target shop + * @param player The player creaing the shop + */ + public ShopCreateEvent(@NotNull Shop shop, @NotNull Player player) { + this.shop = shop; + this.player = player; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopDeleteEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopDeleteEvent.java new file mode 100644 index 0000000..016593e --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopDeleteEvent.java @@ -0,0 +1,59 @@ +/* + * This file is a part of project QuickShop, the name is ShopDeleteEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.abc.A.N.Shop; +import org.bukkit.event.Cancellable; +import org.jetbrains.annotations.NotNull; + +public class ShopDeleteEvent extends QSEvent implements Cancellable { + + @Getter + private final boolean fromMemory; + + @Getter + @NotNull + private final Shop shop; + + private boolean cancelled; + + /** + * Call the event when shop is deleteing. The ShopUnloadEvent will call after ShopDeleteEvent + * + * @param shop Target shop + * @param fromMemory Only delete from the memory? false = delete both in memory and database + */ + public ShopDeleteEvent(@NotNull Shop shop, boolean fromMemory) { + this.shop = shop; + this.fromMemory = fromMemory; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopDisplayItemDespawnEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopDisplayItemDespawnEvent.java new file mode 100644 index 0000000..b5870d5 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopDisplayItemDespawnEvent.java @@ -0,0 +1,84 @@ +/* + * This file is a part of project QuickShop, the name is ShopDisplayItemDespawnEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.abc.A.N.DisplayItem; +import org.abc.A.N.DisplayType; +import org.abc.A.N.Shop; +import org.bukkit.event.Cancellable; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +/** + * This event is called after DisplayItem removed + */ +public class ShopDisplayItemDespawnEvent extends QSEvent implements Cancellable { + + @Getter + @NotNull + private final Shop shop; + + @Getter + @NotNull + private final ItemStack itemStack; + + @Getter + @NotNull + private final DisplayType displayType; + + private boolean cancelled; + + /** + * This event is called before the shop display item created + * + * @param shop Target shop + * @param itemStack Target itemstacck + */ + @Deprecated + public ShopDisplayItemDespawnEvent(@NotNull Shop shop, @NotNull ItemStack itemStack) { + this(shop, itemStack, DisplayItem.getNowUsing()); + } + + /** + * This event is called before the shop display item created + * + * @param shop Target shop + * @param itemStack Target itemstacck + * @param displayType The displayType + */ + public ShopDisplayItemDespawnEvent( + @NotNull Shop shop, @NotNull ItemStack itemStack, @NotNull DisplayType displayType) { + this.shop = shop; + this.itemStack = itemStack; + this.displayType = displayType; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopDisplayItemSpawnEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopDisplayItemSpawnEvent.java new file mode 100644 index 0000000..a114874 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopDisplayItemSpawnEvent.java @@ -0,0 +1,84 @@ +/* + * This file is a part of project QuickShop, the name is ShopDisplayItemSpawnEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.abc.A.N.DisplayItem; +import org.abc.A.N.DisplayType; +import org.abc.A.N.Shop; +import org.bukkit.event.Cancellable; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +/** + * This event is called before the shop display item created + */ +public class ShopDisplayItemSpawnEvent extends QSEvent implements Cancellable { + + @Getter + @NotNull + private final DisplayType displayType; + + @Getter + @NotNull + private final ItemStack itemStack; + + @Getter + @NotNull + private final Shop shop; + + private boolean cancelled; + + /** + * This event is called before the shop display item created + * + * @param shop Target shop + * @param itemStack The ItemStack for spawning the displayItem + */ + @Deprecated + public ShopDisplayItemSpawnEvent(@NotNull Shop shop, @NotNull ItemStack itemStack) { + this(shop, itemStack, DisplayItem.getNowUsing()); + } + + /** + * This event is called before the shop display item created + * + * @param shop Target shop + * @param displayType The displayType + * @param itemStack Target ItemStack + */ + public ShopDisplayItemSpawnEvent( + @NotNull Shop shop, @NotNull ItemStack itemStack, @NotNull DisplayType displayType) { + this.shop = shop; + this.itemStack = itemStack; + this.displayType = displayType; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopInventoryPreviewEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopInventoryPreviewEvent.java new file mode 100644 index 0000000..c14a94b --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopInventoryPreviewEvent.java @@ -0,0 +1,61 @@ +/* + * This file is a part of project QuickShop, the name is ShopInventoryPreviewEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +public class ShopInventoryPreviewEvent extends QSEvent implements Cancellable { + + @Getter + @NotNull + private final ItemStack itemStack; + + @Getter + @NotNull + private final Player player; + + private boolean cancelled; + + /** + * Build a event when player using GUI preview + * + * @param player Target plugin + * @param itemStack The preview item, with preview flag. + */ + public ShopInventoryPreviewEvent(@NotNull Player player, @NotNull ItemStack itemStack) { + this.player = player; + this.itemStack = itemStack; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopLoadEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopLoadEvent.java new file mode 100644 index 0000000..ca1229f --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopLoadEvent.java @@ -0,0 +1,57 @@ +/* + * This file is a part of project QuickShop, the name is ShopLoadEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.abc.A.N.Shop; +import org.bukkit.event.Cancellable; +import org.jetbrains.annotations.NotNull; + +/** + * Call when loading shop + */ +public class ShopLoadEvent extends QSEvent implements Cancellable { + + @Getter + @NotNull + private final Shop shop; + + private boolean cancelled; + + /** + * Calling when shop loading + * + * @param shop Target shop + */ + public ShopLoadEvent(@NotNull Shop shop) { + this.shop = shop; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopModeratorChangedEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopModeratorChangedEvent.java new file mode 100644 index 0000000..e9827c7 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopModeratorChangedEvent.java @@ -0,0 +1,51 @@ +/* + * This file is a part of project QuickShop, the name is ShopModeratorChangedEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.abc.A.N.Shop; +import org.abc.A.N.ShopModerator; +import org.jetbrains.annotations.NotNull; + +/** + * Calling when moderator was changed, Can't cancel + */ +public class ShopModeratorChangedEvent extends QSEvent { + + @Getter + @NotNull + private final ShopModerator moderator; + + @Getter + @NotNull + private final Shop shop; + + /** + * Will call when shop price was changed. + * + * @param shop Target shop + * @param shopModerator The shop moderator + */ + public ShopModeratorChangedEvent(@NotNull Shop shop, @NotNull ShopModerator shopModerator) { + this.shop = shop; + this.moderator = shopModerator; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopPreCreateEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopPreCreateEvent.java new file mode 100644 index 0000000..4af6d9f --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopPreCreateEvent.java @@ -0,0 +1,66 @@ +/* + * This file is a part of project QuickShop, the name is ShopPreCreateEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.jetbrains.annotations.NotNull; + +/** + * This event is called before the shop creation request is sent. E.g. A player clicks a chest, this + * event is thrown, if successful, the player is asked how much they wish to trade for. + */ +public class ShopPreCreateEvent extends QSEvent implements Cancellable { + + @Getter + @NotNull + private final Location location; + + @Getter + @NotNull + private final Player player; + + private boolean cancelled; + + /** + * Calling when shop pre-creating. Shop won't one-percent will create after this event, if you + * want get the shop created event, please use ShopCreateEvent + * + * @param player Target player + * @param location The location will create be shop + */ + public ShopPreCreateEvent(@NotNull Player player, @NotNull Location location) { + this.location = location; + this.player = player; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopPriceChangeEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopPriceChangeEvent.java new file mode 100644 index 0000000..6c0d769 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopPriceChangeEvent.java @@ -0,0 +1,67 @@ +/* + * This file is a part of project QuickShop, the name is ShopPriceChangeEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.abc.A.N.Shop; +import org.bukkit.event.Cancellable; +import org.jetbrains.annotations.NotNull; + +/** + * Calling when shop price was changed, Can't cancel + */ +public class ShopPriceChangeEvent extends QSEvent implements Cancellable { + + @Getter + private final double newPrice; + + @Getter + private final double oldPrice; + + @Getter + @NotNull + private final Shop shop; + + private boolean cancelled; + + /** + * Will call when shop price was changed. + * + * @param shop Target shop + * @param oldPrice The old shop price + * @param newPrice The new shop price + */ + public ShopPriceChangeEvent(@NotNull Shop shop, double oldPrice, double newPrice) { + this.shop = shop; + this.oldPrice = oldPrice; + this.newPrice = newPrice; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopProtectionCheckEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopProtectionCheckEvent.java new file mode 100644 index 0000000..c8f324c --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopProtectionCheckEvent.java @@ -0,0 +1,75 @@ +/* + * This file is a part of project QuickShop, the name is ShopProtectionCheckEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.jetbrains.annotations.NotNull; + +public class ShopProtectionCheckEvent extends QSEvent { + + @Getter + @NotNull + private final Player player; + + @Getter + @NotNull + private final Location loc; + + @NotNull + private final Event event; // Don't use getter, we have important notice need told dev in javadoc. + + @Getter + @NotNull + private final ProtectionCheckStatus status; + + /** + * Will call when shop price was changed. + * + * @param location Target location will execute protect check. + * @param status The checking status + * @param event The event will call to check the permissions. + * @param player The player in was mentions in this event + */ + public ShopProtectionCheckEvent( + @NotNull Location location, + @NotNull Player player, + @NotNull ProtectionCheckStatus status, + @NotNull Event event) { + this.loc = location; + this.player = player; + this.status = status; + this.event = event; + } + + /** + * Get the event will used for permission check. WARN: This might not only BlockBreakEvent, you + * should check the event type before casting. + * + * @return The protection check event. + */ + @NotNull + public Event getEvent() { + return event; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopPurchaseEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopPurchaseEvent.java new file mode 100644 index 0000000..4dc082a --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopPurchaseEvent.java @@ -0,0 +1,67 @@ +/* + * This file is a part of project QuickShop, the name is ShopPurchaseEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.abc.A.N.Shop; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.jetbrains.annotations.NotNull; + +public class ShopPurchaseEvent extends QSEvent implements Cancellable { + + @Getter + @NotNull + private final Shop shop; + + @Getter + @NotNull + private final Player player; + + @Getter + private final int amount; + + private boolean cancelled; + + /** + * Builds a new shop purchase event This time, purchase not start, please listen the + * ShopSuccessPurchaseEvent. + * + * @param shop The shop bought from + * @param player The player buying + * @param amount The amount they're buying + */ + public ShopPurchaseEvent(@NotNull Shop shop, @NotNull Player player, int amount) { + this.shop = shop; + this.player = player; + this.amount = amount; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopSignUpdatedEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopSignUpdatedEvent.java new file mode 100644 index 0000000..cf7bdce --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopSignUpdatedEvent.java @@ -0,0 +1,51 @@ +/* + * This file is a part of project QuickShop, the name is ShopSignUpdatedEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.abc.A.N.Shop; +import org.bukkit.block.Sign; +import org.jetbrains.annotations.NotNull; + +/** + * Calling when shop sign update, Can't cancel + */ +public class ShopSignUpdatedEvent extends QSEvent { + + @Getter + @NotNull + private final Shop shop; + + @Getter + @NotNull + private final Sign sign; + + /** + * Will call when shop price was changed. + * + * @param shop Target shop + * @param sign Updated sign + */ + public ShopSignUpdatedEvent(@NotNull Shop shop, @NotNull Sign sign) { + this.shop = shop; + this.sign = sign; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopSuccessPurchaseEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopSuccessPurchaseEvent.java new file mode 100644 index 0000000..2443378 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopSuccessPurchaseEvent.java @@ -0,0 +1,98 @@ +/* + * This file is a part of project QuickShop, the name is ShopSuccessPurchaseEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.abc.A.N.Shop; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.jetbrains.annotations.NotNull; + +public class ShopSuccessPurchaseEvent extends QSEvent implements Cancellable { + + @Getter + @NotNull + public final Shop shop; + + @Getter + private final int amount; + + @Getter + @NotNull + private final Player player; + + @Getter + private final double tax; + + private final double + total; // Don't use getter, we have important notice need told dev in javadoc. + + private boolean cancelled; + + /** + * Builds a new shop purchase event This time, purchase not start, please listen the + * ShopSuccessPurchaseEvent. + * + * @param shop The shop bought from + * @param player The player buying + * @param amount The amount they're buying + * @param tax The tax in this purchase + * @param total The money in this purchase + */ + public ShopSuccessPurchaseEvent( + @NotNull Shop shop, @NotNull Player player, int amount, double total, double tax) { + this.shop = shop; + this.player = player; + this.amount = amount; + this.tax = tax; + this.total = total; + } + + /** + * The total money changes in this purchase. Calculate tax, if you want get total without tax, + * please use getBalanceWithoutTax() + * + * @return the total money with calculate tax + */ + public double getBalance() { + return this.total * (1 - tax); + } + + /** + * The total money changes in this purchase. No calculate tax, if you want get total with tax, + * please use getBalance() + * + * @return the total money without calculate tax + */ + public double getBalanceWithoutTax() { + return this.total; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopUnloadEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopUnloadEvent.java new file mode 100644 index 0000000..9a18cbc --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopUnloadEvent.java @@ -0,0 +1,44 @@ +/* + * This file is a part of project QuickShop, the name is ShopUnloadEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.abc.A.N.Shop; +import org.jetbrains.annotations.NotNull; + +/** + * Getting the unloading shop, Can't cancel. + */ +public class ShopUnloadEvent extends QSEvent { + + @NotNull + @Getter + private Shop shop; + + /** + * Getting the unloading shop, Can't cancel. + * + * @param shop The shop to unload + */ + public ShopUnloadEvent(@NotNull Shop shop) { + this.shop = shop; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopUpdateEvent.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopUpdateEvent.java new file mode 100644 index 0000000..a5ebade --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/G/ShopUpdateEvent.java @@ -0,0 +1,54 @@ +/* + * This file is a part of project QuickShop, the name is ShopUpdateEvent.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.G; + +import lombok.Getter; +import org.abc.A.N.Shop; +import org.bukkit.event.Cancellable; +import org.jetbrains.annotations.NotNull; + +public class ShopUpdateEvent extends QSEvent implements Cancellable { + + @NotNull + @Getter + private final Shop shop; + + private boolean cancelled; + + /** + * Call when shop is trying updated to database + * + * @param shop The shop bought from + */ + public ShopUpdateEvent(@NotNull Shop shop) { + this.shop = shop; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/newest/ConfigFile.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/newest/ConfigFile.java new file mode 100644 index 0000000..5a9ce58 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/newest/ConfigFile.java @@ -0,0 +1,18 @@ +package org.abc.A.H.newest; + +import io.github.portlek.configs.BukkitManaged; +import io.github.portlek.configs.annotations.Config; +import io.github.portlek.configs.annotations.Value; +import io.github.portlek.configs.util.FileType; + +@Config( + name = "config", + type = FileType.JSON, + location = "%basedir%/QuickShop" +) +public final class ConfigFile extends BukkitManaged { + + @Value + public String plugin_language = "en"; + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/newest/LanguageFile.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/newest/LanguageFile.java new file mode 100644 index 0000000..e53bd0d --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/newest/LanguageFile.java @@ -0,0 +1,38 @@ +package org.abc.A.H.newest; + +import io.github.portlek.configs.BukkitLinkedManaged; +import io.github.portlek.configs.annotations.Config; +import io.github.portlek.configs.annotations.LinkedConfig; +import io.github.portlek.configs.util.FileType; +import org.jetbrains.annotations.NotNull; + +@LinkedConfig(configs = { + @Config( + name = "de", + location = "%basedir%/QuickShop/messages", + copyDefault = true, + type = FileType.JSON, + resourcePath = "messages" + ), + @Config( + name = "en", + location = "%basedir%/QuickShop/messages", + copyDefault = true, + type = FileType.JSON, + resourcePath = "messages" + ), + @Config( + name = "en-US", + location = "%basedir%/QuickShop/messages", + copyDefault = true, + type = FileType.JSON, + resourcePath = "messages" + ) +}) +public final class LanguageFile extends BukkitLinkedManaged { + + public LanguageFile(@NotNull final String language) { + super(language); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/FileEnvelope.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/FileEnvelope.java new file mode 100644 index 0000000..f79bcd0 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/FileEnvelope.java @@ -0,0 +1,245 @@ +package org.abc.A.H.old; + +import java.io.File; +import java.io.InputStream; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import lombok.ToString; +import org.abc.A.util.Copied; +import org.abc.A.util.Util; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.K.MckFileConfiguration; +import org.abc.A.util.location.LocationOf; +import org.abc.A.util.location.StringOf; + +@ToString +public abstract class FileEnvelope implements IFile { + + @NotNull + protected final File file; + + protected final boolean loadDefault; + + @NotNull + private final Plugin plugin; + + @NotNull + private final Copied copied; + + @NotNull + private final String resourcePath; + + @NotNull + protected FileConfiguration fileConfiguration = new MckFileConfiguration(); + + public FileEnvelope(@NotNull Plugin plugin, @NotNull File file, @NotNull String resourcePath, boolean loadDefault) { + this.plugin = plugin; + this.file = file; + this.copied = new Copied(file); + this.resourcePath = resourcePath; + this.loadDefault = loadDefault; + } + + @Override + public void create() { + if (file.exists()) { + reload(); + return; + } + + try { + final File parent = file.getParentFile(); + + if (parent != null) { + parent.mkdirs(); + } + + file.createNewFile(); + } catch (Exception exception) { + throw new RuntimeException(exception); + } + + if (loadDefault) { + copied.accept(getInputStream()); + } + + reload(); + } + + @NotNull + @Override + public InputStream getInputStream() { + return Objects.requireNonNull(plugin.getResource(resourcePath)); + } + + @Override + public void save() { + try { + if (fileConfiguration instanceof MckFileConfiguration) { + reload(); + } + + fileConfiguration.save(file); + } catch (Exception exception) { + throw new IllegalStateException(exception); + } + } + + @NotNull + @Override + public String saveToString() { + return fileConfiguration.saveToString(); + } + + @Override + public void loadFromString(@NotNull String data) throws InvalidConfigurationException { + fileConfiguration.loadFromString(data); + } + + @Nullable + @Override + public Object get(@NotNull String path) { + return fileConfiguration.get(path); + } + + @Nullable + @Override + public Object get(@NotNull String path, @Nullable Object fallback) { + final Object object = fileConfiguration.get(path, fallback); + + if (object == null) { + return fallback; + } + + return object; + } + + @NotNull + @Override + @SuppressWarnings("unchecked") + public T getOrSet(@NotNull String path, @NotNull T fallback) { + final T object = (T) fileConfiguration.get(path, null); + + if (object != null) { + return object; + } + + set(path, fallback); + + return fallback; + } + + @NotNull + @Override + public Location getLocation(@NotNull String path) { + return new LocationOf(getString(path).orElse("")).value(); + } + + @Override + public void setLocation(@NotNull String path, @NotNull Location location) { + set(path, new StringOf(location).asString()); + } + + @NotNull + @Override + public ItemStack getCustomItemStack(@NotNull String path) { + try { + return Util.deserialize(path); + } catch (Exception exception) { + return new ItemStack(Material.AIR); + } + } + + @Override + public void setCustomItemStack(@NotNull String path, @NotNull ItemStack itemStack) { + fileConfiguration.set(path, Util.serialize(itemStack)); + } + + @NotNull + @Override + public Optional getString(@NotNull String path) { + return Optional.ofNullable(fileConfiguration.getString(path)); + } + + @Override + public void set(@NotNull String path, @Nullable Object object) { + fileConfiguration.set(path, object); + save(); + } + + @NotNull + @Override + public List getStringList(@NotNull String path) { + return fileConfiguration.getStringList(path); + } + + @Override + public int getInt(@NotNull String path) { + return fileConfiguration.getInt(path); + } + + @Override + public double getDouble(@NotNull String path) { + return fileConfiguration.getDouble(path); + } + + @Override + public long getLong(@NotNull String path) { + return fileConfiguration.getLong(path); + } + + @Override + public byte getByte(@NotNull String path) { + return (byte) fileConfiguration.getInt(path); + } + + @Override + public short getShort(@NotNull String path) { + return (short) fileConfiguration.getInt(path); + } + + @Override + public boolean getBoolean(@NotNull String path) { + return fileConfiguration.getBoolean(path); + } + + @NotNull + @Override + public ConfigurationSection createSection(@NotNull String path) { + final ConfigurationSection configurationSection = fileConfiguration.createSection(path); + + save(); + + return configurationSection; + } + + @NotNull + @Override + public ConfigurationSection getSection(@NotNull String path) { + final ConfigurationSection configurationSection = fileConfiguration.getConfigurationSection(path); + + return configurationSection == null ? new MckFileConfiguration() : configurationSection; + } + + @NotNull + @Override + public ConfigurationSection getOrCreateSection(@NotNull String path) { + ConfigurationSection section = getSection(path); + + if (section instanceof MckFileConfiguration) { + section = createSection(path); + } + + return section; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/IFile.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/IFile.java new file mode 100644 index 0000000..3142fb0 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/IFile.java @@ -0,0 +1,204 @@ +package org.abc.A.H.old; + +import java.io.InputStream; +import java.util.List; +import java.util.Optional; +import org.bukkit.Location; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.K.MckFileConfiguration; + +public interface IFile { + + /** + * Creates yml file on the path + */ + void create(); + + @NotNull InputStream getInputStream(); + + /** + * Reloads file + */ + void reload(); + + /** + * Saves file + */ + void save(); + + /** + * @return the string of the file + */ + @NotNull String saveToString(); + + /** + * Loads from the data + * + * @param data the data + * @throws InvalidConfigurationException if config is invalid + */ + void loadFromString(@NotNull String data) throws InvalidConfigurationException; + + /** + * Gets the object + * + * @param path object path to get + * @return if path does not exist returns null + */ + @Nullable Object get(@NotNull String path); + + /** + * Gets the object with fallback + * + * @param path object path to get + * @param fallback fallback object to get if path does not exist + * @return if path does not exist returns fallback object + */ + @Nullable Object get(@NotNull String path, @Nullable Object fallback); + + /** + * Gets or sets the object + * + * @param path object path to get + * @param fallback fallback object to get if path does not exist + * @param object type + * @return if path does not exist returns and set the path with fallback object + */ + @NotNull T getOrSet(@NotNull final String path, @NotNull T fallback); + + /** + * Gets location + * + * @param path location path to get + * @return {@link Location} + */ + @NotNull Location getLocation(@NotNull final String path); + + /** + * Sets location into the path + * + * @param path location path to set + * @param location {@link Location} + */ + void setLocation(@NotNull final String path, @NotNull final Location location); + + /** + * Pattern: + * + *

path: (material): 'DIAMOND' [amount]: 1 [data]: 0 [display-name]: 'Diamond Sword' + * [enchants]: DAMAGE_ALL: 10 FIRE_ASPECT: 2 [lore]: - 'Lore 1' - 'Lore 2' + * + * @param path itemstack path to get + * @return {@link ItemStack} + */ + @NotNull ItemStack getCustomItemStack(@NotNull final String path); + + /** + * Sets custom itemstack to path + * + * @param path itemstack path to set + * @param itemStack {@link ItemStack} + */ + void setCustomItemStack(@NotNull final String path, @NotNull final ItemStack itemStack); + + /** + * Gets string + * + * @param path string path to get + * @return {@link String} + */ + @NotNull Optional getString(@NotNull final String path); + + /** + * Sets object to path + * + * @param path object path to set + * @param object {@link Object} + */ + void set(@NotNull final String path, @Nullable final Object object); + + /** + * Gets string list + * + * @param path string list path to get + * @return string list + */ + @NotNull List getStringList(@NotNull final String path); + + /** + * Gets int + * + * @param path integer path to get + * @return {@link Integer} + */ + int getInt(@NotNull final String path); + + /** + * Gets double + * + * @param path double path to get + * @return {@link Double} + */ + double getDouble(@NotNull final String path); + + /** + * Gets long + * + * @param path long path to get + * @return {@link Integer} + */ + long getLong(@NotNull String path); + + /** + * Gets byte + * + * @param path byte path to get + * @return {@link Byte} + */ + byte getByte(@NotNull final String path); + + /** + * Gets short + * + * @param path short path to get + * @return {@link Short} + */ + short getShort(@NotNull String path); + + /** + * Gets boolean + * + * @param path boolean path to get + * @return {@link Boolean} + */ + boolean getBoolean(@NotNull final String path); + + /** + * Creates configuration section into path + * + * @param path configuration section path to create + * @return {@link ConfigurationSection} + */ + @NotNull ConfigurationSection createSection(@NotNull String path); + + /** + * Gets configuration section from path + * + * @param path configurations section path to get + * @return if there isn't section returns {@link MckFileConfiguration} + */ + @NotNull ConfigurationSection getSection(@NotNull final String path); + + /** + * Gets configuration section from path if there is no section It will create + * + * @param path configurations section path to get + * @return {@link ConfigurationSection} + */ + @NotNull ConfigurationSection getOrCreateSection(@NotNull final String path); + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/JSONFile.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/JSONFile.java new file mode 100644 index 0000000..8279439 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/JSONFile.java @@ -0,0 +1,36 @@ +package org.abc.A.H.old; + +import java.io.File; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import org.abc.A.L.com.dumbtruckman.JsonConfiguration.JSONConfiguration; + +public final class JSONFile extends FileEnvelope { + + public JSONFile(@NotNull final Plugin plugin, @NotNull final File file, @NotNull final String resourcePath, boolean loadDefault) { + super(plugin, file, resourcePath.endsWith(".json") ? resourcePath : resourcePath + ".json", loadDefault); + } + + public JSONFile(@NotNull final Plugin plugin, @NotNull final String fileName) { + this(plugin, "", fileName); + } + + public JSONFile(@NotNull final Plugin plugin, @NotNull final String resourcePath, @NotNull final String fileName) { + this(plugin, new File(plugin.getDataFolder().getAbsolutePath() + (resourcePath.startsWith("/") ? resourcePath : "/" + resourcePath), fileName.endsWith(".json") ? fileName : fileName + ".json"), resourcePath.isEmpty() ? fileName : resourcePath.endsWith("/") ? resourcePath + fileName : resourcePath + "/" + fileName); + } + + public JSONFile(@NotNull final Plugin plugin, @NotNull final File file, @NotNull final String resourcePath) { + super(plugin, file, resourcePath.endsWith(".json") ? resourcePath : resourcePath + ".json", true); + } + + @Override + public void reload() { + fileConfiguration = JSONConfiguration.loadConfiguration(file); + if (loadDefault) { + fileConfiguration.setDefaults(JSONConfiguration.loadConfiguration(new InputStreamReader(getInputStream(), StandardCharsets.UTF_8))); + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/YAMLFile.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/YAMLFile.java new file mode 100644 index 0000000..08739e7 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/H/old/YAMLFile.java @@ -0,0 +1,35 @@ +package org.abc.A.H.old; + +import java.io.File; +import java.io.InputStreamReader; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +public final class YAMLFile extends FileEnvelope { + + public YAMLFile(@NotNull final Plugin plugin, @NotNull final File file, @NotNull final String resourcePath, boolean loadDefault) { + super(plugin, file, resourcePath.endsWith(".yml") ? resourcePath : resourcePath + ".yml", loadDefault); + } + + public YAMLFile(@NotNull final Plugin plugin, @NotNull final String fileName) { + this(plugin, "", fileName); + } + + public YAMLFile(@NotNull final Plugin plugin, @NotNull final String resourcePath, @NotNull final String fileName) { + this(plugin, new File(plugin.getDataFolder().getAbsolutePath() + (resourcePath.startsWith("/") ? resourcePath : "/" + resourcePath), fileName.endsWith(".yml") ? fileName : fileName + ".yml"), resourcePath.isEmpty() ? fileName : resourcePath.endsWith("/") ? resourcePath + fileName : resourcePath + "/" + fileName); + } + + public YAMLFile(@NotNull final Plugin plugin, @NotNull final File file, @NotNull final String resourcePath) { + super(plugin, file, resourcePath.endsWith(".yml") ? resourcePath : resourcePath + ".yml", true); + } + + @Override + public void reload() { + fileConfiguration = YamlConfiguration.loadConfiguration(file); + if (loadDefault) { + fileConfiguration.setDefaults(YamlConfiguration.loadConfiguration(new InputStreamReader(getInputStream()))); + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/FactionsUUID/FactionsUUIDIntegration.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/FactionsUUID/FactionsUUIDIntegration.java new file mode 100644 index 0000000..0fbfae5 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/FactionsUUID/FactionsUUIDIntegration.java @@ -0,0 +1,213 @@ +/* + * This file is a part of project QuickShop, the name is FactionsUUIDIntegration.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.I.FactionsUUID; + +import com.massivecraft.factions.Board; +import com.massivecraft.factions.FLocation; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.perms.PermissibleAction; +import java.util.List; + +import org.abc.A.QuickShop; +import org.abc.A.I.IntegrateStage; +import org.abc.A.I.IntegratedPlugin; +import org.abc.A.I.IntegrationStage; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +@IntegrationStage(loadStage = IntegrateStage.onEnableAfter) +public class FactionsUUIDIntegration implements IntegratedPlugin { + private final List createFlags; + + private final List tradeFlags; + + private final boolean createRequireOpen; + + private final boolean createRequireNormal; + + private final boolean createRequireWilderness; + + private final boolean createRequirePeaceful; + + private final boolean createRequirePermanent; + + private final boolean createRequireSafeZone; + + private final boolean createRequireOwn; + + private final boolean createRequireWarZone; + + private final boolean tradeRequireOpen; + + private final boolean tradeRequireNormal; + + private final boolean tradeRequireWilderness; + + private final boolean tradeRequirePeaceful; + + private final boolean tradeRequirePermanent; + + private final boolean tradeRequireSafeZone; + + private final boolean tradeRequireOwn; + + private final boolean tradeRequireWarZone; + + public FactionsUUIDIntegration(QuickShop plugin) { + this.createFlags = plugin.getConfig().getStringList("integration.factions.create.flags"); + this.tradeFlags = plugin.getConfig().getStringList("integration.factions.trade.flags"); + + this.createRequireOpen = + plugin.getConfig().getBoolean("integration.factions.create.require.open"); + this.createRequireNormal = + plugin.getConfig().getBoolean("integration.factions.create.require.normal"); + this.createRequireWilderness = + plugin.getConfig().getBoolean("integration.factions.create.require.wilderness"); + this.createRequirePeaceful = + plugin.getConfig().getBoolean("integration.factions.create.require.peaceful"); + this.createRequirePermanent = + plugin.getConfig().getBoolean("integration.factions.create.require.permanent"); + this.createRequireSafeZone = + plugin.getConfig().getBoolean("integration.factions.create.require.safezone"); + this.createRequireOwn = + plugin.getConfig().getBoolean("integration.factions.create.require.own"); + this.createRequireWarZone = + plugin.getConfig().getBoolean("integration.factions.create.require.warzone"); + + this.tradeRequireOpen = + plugin.getConfig().getBoolean("integration.factions.trade.require.open"); + this.tradeRequireNormal = + plugin.getConfig().getBoolean("integration.factions.trade.require.normal"); + this.tradeRequireWilderness = + plugin.getConfig().getBoolean("integration.factions.trade.require.wilderness"); + this.tradeRequirePeaceful = + plugin.getConfig().getBoolean("integration.factions.trade.require.peaceful"); + this.tradeRequirePermanent = + plugin.getConfig().getBoolean("integration.factions.trade.require.permanent"); + this.tradeRequireSafeZone = + plugin.getConfig().getBoolean("integration.factions.trade.require.safezone"); + this.tradeRequireOwn = plugin.getConfig().getBoolean("integration.factions.trade.require.own"); + this.tradeRequireWarZone = + plugin.getConfig().getBoolean("integration.factions.trade.require.warzone"); + } + + @Override + public @NotNull String getName() { + return "Factions"; + } + + @Override + public boolean canCreateShopHere(@NotNull Player player, @NotNull Location location) { + Faction faction = Board.getInstance().getFactionAt(new FLocation(location)); + if (faction == null) { + return true; + } + if (createRequireOpen && !faction.getOpen()) { + return false; + } + if (createRequireSafeZone && !faction.isSafeZone()) { + return false; + } + if (createRequirePermanent && !faction.isPermanent()) { + return false; + } + if (createRequirePeaceful && !faction.isPeaceful()) { + return false; + } + if (createRequireWilderness && !faction.isWilderness()) { + return false; + } + if (createRequireOpen && !faction.getOpen()) { + return false; + } + if (createRequireWarZone && !faction.isWarZone()) { + return false; + } + if (createRequireNormal && !faction.isNormal()) { + return false; + } + if (createRequireOwn + && !faction.getOwnerList(new FLocation(location)).contains(player.getName())) { + return false; + } + for (String flag : createFlags) { + if (!faction.hasAccess( + FPlayers.getInstance().getByPlayer(player), PermissibleAction.fromString(flag))) { + return false; + } + } + return true; + } + + @Override + public boolean canTradeShopHere(@NotNull Player player, @NotNull Location location) { + + Faction faction = Board.getInstance().getFactionAt(new FLocation(location)); + if (faction == null) { + return true; + } + if (tradeRequireOpen && !faction.getOpen()) { + return false; + } + if (tradeRequireSafeZone && !faction.isSafeZone()) { + return false; + } + if (tradeRequirePermanent && !faction.isPermanent()) { + return false; + } + if (tradeRequirePeaceful && !faction.isPeaceful()) { + return false; + } + if (tradeRequireWilderness && !faction.isWilderness()) { + return false; + } + if (tradeRequireOpen && !faction.getOpen()) { + return false; + } + if (tradeRequireWarZone && !faction.isWarZone()) { + return false; + } + if (tradeRequireNormal && !faction.isNormal()) { + return false; + } + if (tradeRequireOwn + && !faction.getOwnerList(new FLocation(location)).contains(player.getName())) { + return false; + } + for (String flag : tradeFlags) { + if (!faction.hasAccess( + FPlayers.getInstance().getByPlayer(player), PermissibleAction.fromString(flag))) { + return false; + } + } + return true; + } + + @Override + public void load() { + } + + @Override + public void unload() { + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/IntegrateStage.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/IntegrateStage.java new file mode 100644 index 0000000..9743e62 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/IntegrateStage.java @@ -0,0 +1,29 @@ +/* + * This file is a part of project QuickShop, the name is IntegrateStage.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.I; + +public enum IntegrateStage { + onLoadBegin, + onLoadAfter, + onEnableBegin, + onEnableAfter, + onUnloadBegin, + onUnloadAfter +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/IntegratedPlugin.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/IntegratedPlugin.java new file mode 100644 index 0000000..14390f0 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/IntegratedPlugin.java @@ -0,0 +1,38 @@ +/* + * This file is a part of project QuickShop, the name is IntegratedPlugin.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.I; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +public interface IntegratedPlugin { + @NotNull + String getName(); + + boolean canCreateShopHere(@NotNull Player player, @NotNull Location location); + + boolean canTradeShopHere(@NotNull Player player, @NotNull Location location); + + void load(); + + void unload(); + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/IntegrationStage.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/IntegrationStage.java new file mode 100644 index 0000000..9cf6d76 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/IntegrationStage.java @@ -0,0 +1,33 @@ +/* + * This file is a part of project QuickShop, the name is IntegrationStage.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.I; + +import java.lang.annotation.*; + +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Inherited +public @interface IntegrationStage { + IntegrateStage loadStage() default IntegrateStage.onEnableAfter; + + IntegrateStage unloadStage() default IntegrateStage.onUnloadBegin; + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/PlotSquared/PlotSquaredIntegration.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/PlotSquared/PlotSquaredIntegration.java new file mode 100644 index 0000000..a860631 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/PlotSquared/PlotSquaredIntegration.java @@ -0,0 +1,92 @@ +/* + * This file is a part of project QuickShop, the name is PlotSquaredIntegration.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.I.PlotSquared; + +import com.github.intellectualsites.plotsquared.plot.flag.BooleanFlag; +import com.github.intellectualsites.plotsquared.plot.flag.Flags; +import com.github.intellectualsites.plotsquared.plot.object.Plot; +import org.abc.A.QuickShop; +import org.abc.A.I.IntegrateStage; +import org.abc.A.I.IntegratedPlugin; +import org.abc.A.I.IntegrationStage; +import org.abc.A.util.Util; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +@SuppressWarnings("DuplicatedCode") +@IntegrationStage(loadStage = IntegrateStage.onEnableAfter) +public class PlotSquaredIntegration implements IntegratedPlugin { + private final QuickShop plugin; + + private BooleanFlag createFlag; + + private BooleanFlag tradeFlag; + + public PlotSquaredIntegration(QuickShop plugin) { + this.plugin = plugin; + // PlotAPI plotAPI = new PlotAPI(); + } + + @Override + public @NotNull String getName() { + return "PlotSquared"; + } + + @Override + public boolean canCreateShopHere(@NotNull Player player, @NotNull Location location) { + com.github.intellectualsites.plotsquared.plot.object.Location pLocation = + new com.github.intellectualsites.plotsquared.plot.object.Location( + location.getWorld().getName(), + location.getBlockX(), + location.getBlockY(), + location.getBlockZ()); + Plot plot = pLocation.getPlot(); + return this.createFlag.isTrue(plot); + } + + @Override + public boolean canTradeShopHere(@NotNull Player player, @NotNull Location location) { + com.github.intellectualsites.plotsquared.plot.object.Location pLocation = + new com.github.intellectualsites.plotsquared.plot.object.Location( + location.getWorld().getName(), + location.getBlockX(), + location.getBlockY(), + location.getBlockZ()); + Plot plot = pLocation.getPlot(); + return this.tradeFlag.isFalse(plot); + } + + @Override + public void load() { + this.createFlag = new BooleanFlag("quickshop-create"); + this.tradeFlag = new BooleanFlag("quickshop-trade"); + Flags.registerFlag(this.createFlag); + Flags.registerFlag(this.tradeFlag); + plugin.getLogger().info(ChatColor.GREEN + getName() + " flags register successfully."); + Util.debugLog("Success register " + getName() + " flags."); + } + + @Override + public void unload() { + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/Residence/ResidenceIntegration.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/Residence/ResidenceIntegration.java new file mode 100644 index 0000000..6ccc80e --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/Residence/ResidenceIntegration.java @@ -0,0 +1,141 @@ +/* + * This file is a part of project QuickShop, the name is ResidenceIntegration.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.I.Residence; + +import com.bekvon.bukkit.residence.Residence; +import com.bekvon.bukkit.residence.containers.Flags; +import com.bekvon.bukkit.residence.protection.ClaimedResidence; +import com.bekvon.bukkit.residence.protection.FlagPermissions; +import java.util.List; + +import org.abc.A.QuickShop; +import org.abc.A.I.IntegrateStage; +import org.abc.A.I.IntegratedPlugin; +import org.abc.A.I.IntegrationStage; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +@SuppressWarnings("DuplicatedCode") +@IntegrationStage(loadStage = IntegrateStage.onEnableAfter) +public class ResidenceIntegration implements IntegratedPlugin { + final List createLimits; + + final List tradeLimits; + + public ResidenceIntegration(QuickShop plugin) { + this.createLimits = plugin.getConfig().getStringList("integration.residence.create"); + this.tradeLimits = plugin.getConfig().getStringList("integration.residence.trade"); + } + + @Override + public @NotNull String getName() { + return "Residence"; + } + + @Override + public boolean canCreateShopHere(@NotNull Player player, @NotNull Location location) { + ClaimedResidence residence = Residence.getInstance().getResidenceManager().getByLoc(location); + + for (String limit : this.createLimits) { + if ("FLAG".equalsIgnoreCase(limit)) { + if (residence == null) { + // Check world permission + if (!Residence.getInstance() + .getWorldFlags() + .getPerms(location.getWorld().getName()) + .playerHas(player, Flags.getFlag("quickshop-create"), false)) { + return false; + } + } else { + if (!residence + .getPermissions() + .playerHas(player, Flags.getFlag("quickshop-create"), false)) { + return false; + } + } + } + // Not flag + if (residence == null) { + if (!Residence.getInstance() + .getWorldFlags() + .getPerms(location.getWorld().getName()) + .playerHas(player, Flags.getFlag(limit), false)) { + return false; + } + } else { + if (!residence.getPermissions().playerHas(player, Flags.getFlag(limit), false)) { + return false; + } + } + } + return false; + } + + @Override + public boolean canTradeShopHere(@NotNull Player player, @NotNull Location location) { + ClaimedResidence residence = Residence.getInstance().getResidenceManager().getByLoc(location); + + for (String limit : this.tradeLimits) { + if ("FLAG".equalsIgnoreCase(limit)) { + if (residence == null) { + // Check world permission + if (!Residence.getInstance() + .getWorldFlags() + .getPerms(location.getWorld().getName()) + .playerHas(player, Flags.getFlag("quickshop-trade"), false)) { + return false; + } + } else { + if (!residence + .getPermissions() + .playerHas(player, Flags.getFlag("quickshop-trade"), true)) { + return false; + } + } + } + // Not flag + if (residence == null) { + if (!Residence.getInstance() + .getWorldFlags() + .getPerms(location.getWorld().getName()) + .playerHas(player, Flags.getFlag(limit), false)) { + return false; + } + } else { + if (!residence.getPermissions().playerHas(player, Flags.getFlag(limit), false)) { + return false; + } + } + } + return false; + } + + @Override + public void load() { + FlagPermissions.addFlag("quickshop.create"); + FlagPermissions.addFlag("quickshop.trade"); + } + + @Override + public void unload() { + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/Towny/TownyFlags.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/Towny/TownyFlags.java new file mode 100644 index 0000000..5b9bb6f --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/Towny/TownyFlags.java @@ -0,0 +1,41 @@ +/* + * This file is a part of project QuickShop, the name is TownyFlags.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.I.Towny; + +import java.util.ArrayList; +import java.util.List; + +public enum TownyFlags { + OWN, + MODIFY, + SHOPTYPE; + + public static List deserialize(List list) { + List result = new ArrayList<>(); + list.forEach(v -> result.add(TownyFlags.valueOf(v.toUpperCase()))); + return result; + } + + public static List serialize(List list) { + List result = new ArrayList<>(); + list.forEach(v -> result.add(v.name())); + return result; + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/Towny/TownyIntegration.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/Towny/TownyIntegration.java new file mode 100644 index 0000000..4efec5c --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/Towny/TownyIntegration.java @@ -0,0 +1,109 @@ +/* + * This file is a part of project QuickShop, the name is PlotSquaredIntegration.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.I.Towny; + +import com.palmergames.bukkit.towny.utils.ShopPlotUtil; +import java.util.List; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.abc.A.I.IntegrateStage; +import org.abc.A.I.IntegratedPlugin; +import org.abc.A.I.IntegrationStage; +import org.abc.A.QuickShop; + +@SuppressWarnings("DuplicatedCode") +@IntegrationStage(loadStage = IntegrateStage.onEnableAfter) +public class TownyIntegration implements IntegratedPlugin { + private final List createFlags; + + private final List tradeFlags; + + public TownyIntegration(QuickShop plugin) { + createFlags = + TownyFlags.deserialize(plugin.getConfig().getStringList("integration.towny.create")); + tradeFlags = + TownyFlags.deserialize(plugin.getConfig().getStringList("integration.towny.trade")); + } + + @Override + public @NotNull String getName() { + return "Towny"; + } + + @Override + public boolean canCreateShopHere(@NotNull Player player, @NotNull Location location) { + for (TownyFlags flag : createFlags) { + switch (flag) { + case OWN: + if (!ShopPlotUtil.doesPlayerOwnShopPlot(player, location)) { + return false; + } + break; + case MODIFY: + if (!ShopPlotUtil.doesPlayerHaveAbilityToEditShopPlot(player, location)) { + return false; + } + break; + case SHOPTYPE: + if (!ShopPlotUtil.isShopPlot(location)) { + return false; + } + default: + // Ignore + } + } + return true; + } + + @Override + public boolean canTradeShopHere(@NotNull Player player, @NotNull Location location) { + for (TownyFlags flag : tradeFlags) { + switch (flag) { + case OWN: + if (!ShopPlotUtil.doesPlayerOwnShopPlot(player, location)) { + return false; + } + break; + case MODIFY: + if (!ShopPlotUtil.doesPlayerHaveAbilityToEditShopPlot(player, location)) { + return false; + } + break; + case SHOPTYPE: + if (!ShopPlotUtil.isShopPlot(location)) { + return false; + } + default: + // Ignore + } + } + return true; + } + + @Override + public void load() { + } + + @Override + public void unload() { + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/WorldGuard/WorldGuardFlags.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/WorldGuard/WorldGuardFlags.java new file mode 100644 index 0000000..c561bf7 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/WorldGuard/WorldGuardFlags.java @@ -0,0 +1,42 @@ +/* + * This file is a part of project QuickShop, the name is WorldGuardFlags.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.I.WorldGuard; + +import java.util.ArrayList; +import java.util.List; + +public enum WorldGuardFlags { + FLAG, + BUILD, + CHEST_ACCESS, + INTERACT; + + public static List deserialize(List list) { + List result = new ArrayList<>(); + list.forEach(v -> result.add(WorldGuardFlags.valueOf(v.toUpperCase()))); + return result; + } + + public static List serialize(List list) { + List result = new ArrayList<>(); + list.forEach(v -> result.add(v.name())); + return result; + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/WorldGuard/WorldGuardIntegration.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/WorldGuard/WorldGuardIntegration.java new file mode 100644 index 0000000..9eb67eb --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/I/WorldGuard/WorldGuardIntegration.java @@ -0,0 +1,181 @@ +/* + * This file is a part of project QuickShop, the name is WorldGuardIntegration.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.I.WorldGuard; + +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldguard.LocalPlayer; +import com.sk89q.worldguard.WorldGuard; +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.protection.flags.Flags; +import com.sk89q.worldguard.protection.flags.StateFlag; +import com.sk89q.worldguard.protection.flags.registry.FlagConflictException; +import com.sk89q.worldguard.protection.flags.registry.FlagRegistry; +import com.sk89q.worldguard.protection.regions.RegionContainer; +import com.sk89q.worldguard.protection.regions.RegionQuery; +import java.util.List; + +import org.abc.A.QuickShop; +import org.abc.A.I.IntegrateStage; +import org.abc.A.I.IntegratedPlugin; +import org.abc.A.I.IntegrationStage; +import org.abc.A.util.Util; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +@SuppressWarnings("DuplicatedCode") +@IntegrationStage(loadStage = IntegrateStage.onLoadAfter) +public class WorldGuardIntegration implements IntegratedPlugin { + private final List createFlags; + + private final List tradeFlags; + + private final StateFlag createFlag = new StateFlag("quickshop-create", false); + + private final StateFlag tradeFlag = new StateFlag("quickshop-trade", true); + + private final QuickShop plugin; + + public WorldGuardIntegration(QuickShop plugin) { + this.plugin = plugin; + createFlags = + WorldGuardFlags.deserialize( + plugin.getConfig().getStringList("integration.worldguard.create")); + tradeFlags = + WorldGuardFlags.deserialize( + plugin.getConfig().getStringList("integration.worldguard.trade")); + } + + @Override + public void load() { + FlagRegistry registry = WorldGuard.getInstance().getFlagRegistry(); + try { + // create a flag with the name "my-custom-flag", defaulting to true + registry.register(this.createFlag); + registry.register(this.tradeFlag); + plugin.getLogger().info(ChatColor.GREEN + getName() + " flags register successfully."); + Util.debugLog("Success register " + getName() + " flags."); + } catch (FlagConflictException e) { + e.printStackTrace(); + } + } + + @Override + public void unload() { + } + + @Override + public @NotNull String getName() { + return "WorldGuard"; + } + + @Override + public boolean canCreateShopHere(@NotNull Player player, @NotNull Location location) { + LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player); + com.sk89q.worldedit.util.Location wgLoc = BukkitAdapter.adapt(location); + boolean canBypass = + WorldGuard.getInstance() + .getPlatform() + .getSessionManager() + .hasBypass(localPlayer, BukkitAdapter.adapt(location.getWorld())); + if (canBypass) { + Util.debugLog( + "Player " + + player.getName() + + " bypassing the protection checks, because player have bypass permission in WorldGuard"); + return true; + } + RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); + RegionQuery query = container.createQuery(); + for (WorldGuardFlags flag : createFlags) { + switch (flag) { + case BUILD: + if (query.queryState(wgLoc, localPlayer, Flags.BUILD) == StateFlag.State.DENY) { + return false; + } + break; + case FLAG: + if (query.queryState(wgLoc, localPlayer, this.createFlag) == StateFlag.State.DENY) { + return false; + } + break; + case CHEST_ACCESS: + if (query.queryState(wgLoc, localPlayer, Flags.CHEST_ACCESS) == StateFlag.State.DENY) { + return false; + } + break; + case INTERACT: + if (query.queryState(wgLoc, localPlayer, Flags.INTERACT) == StateFlag.State.DENY) { + return false; + } + break; + } + } + return true; + } + + @Override + public boolean canTradeShopHere(@NotNull Player player, @NotNull Location location) { + LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player); + com.sk89q.worldedit.util.Location wgLoc = BukkitAdapter.adapt(location); + boolean canBypass = + WorldGuard.getInstance() + .getPlatform() + .getSessionManager() + .hasBypass(localPlayer, BukkitAdapter.adapt(location.getWorld())); + if (canBypass) { + Util.debugLog( + "Player " + + player.getName() + + " bypassing the protection checks, because player have bypass permission in WorldGuard"); + return true; + } + RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); + RegionQuery query = container.createQuery(); + for (WorldGuardFlags flag : tradeFlags) { + switch (flag) { + case BUILD: + if (!query.testState(wgLoc, localPlayer, Flags.BUILD)) { + return false; + } + + break; + case FLAG: + if (!query.testState(wgLoc, localPlayer, this.tradeFlag)) { + return false; + } + break; + case CHEST_ACCESS: + if (!query.testState(wgLoc, localPlayer, Flags.CHEST_ACCESS)) { + return false; + } + break; + case INTERACT: + if (!query.testState(wgLoc, localPlayer, Flags.INTERACT)) { + return false; + } + break; + } + } + return true; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/BlockListener.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/BlockListener.java new file mode 100644 index 0000000..3dcc8f1 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/BlockListener.java @@ -0,0 +1,267 @@ +/* + * This file is a part of project QuickShop, the name is BlockListener.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.J; + +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.Chest; +import org.bukkit.block.Sign; +import org.bukkit.block.data.Directional; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.inventory.DoubleChestInventory; +import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.Cache; +import org.abc.A.QuickShop; +import org.abc.A.N.Info; +import org.abc.A.N.Shop; +import org.abc.A.N.ShopAction; + +public class BlockListener extends ProtectionListenerBase implements Listener { + + public BlockListener(@NotNull final QuickShop plugin, @Nullable final Cache cache) { + super(plugin, cache); + } + + /* + * Removes chests when they're destroyed. + */ + @EventHandler(priority = EventPriority.LOW) + public void onBreak(BlockBreakEvent e) { + + final Block b = e.getBlock(); + + if (b.getState() instanceof Sign) { + Sign sign = (Sign) b.getState(); + if (super.getPlugin().getConfig().getBoolean("lockette.enable") + && sign.getLine(0).equals(super.getPlugin().getConfig().getString("lockette.private")) + || sign.getLine(0).equals(super.getPlugin().getConfig().getString("lockette.more_users"))) { + // Ignore break lockette sign + super.getPlugin().getLogger() + .info("Skipped a dead-lock shop sign.(Lockette or other sign-lock plugin)"); + return; + } + } + + final Player p = e.getPlayer(); + // If the shop was a chest + if (Util.canBeShop(b)) { + final Shop shop = getShopPlayer(b.getLocation(), false); + if (shop == null) { + return; + } + // If they're either survival or the owner, they can break it + if (p.getGameMode() == GameMode.CREATIVE && !p.getUniqueId().equals(shop.getOwner())) { + // Check SuperTool + if (p.getInventory().getItemInMainHand().getType() == Material.GOLDEN_AXE) { + if(getPlugin().getConfig().getBoolean("shop.disable-super-tool")){ + e.setCancelled(true); + MsgUtil.sendMessage(p,MsgUtil.getMessage("supertool-is-disabled", p)); + return; + } + MsgUtil.sendMessage(p,MsgUtil.getMessage("break-shop-use-supertool", p)); + return; + } + e.setCancelled(true); + MsgUtil.sendMessage(p, + MsgUtil.getMessage( + "no-creative-break", p, MsgUtil.getItemi18n(Material.GOLDEN_AXE.name()))); + return; + } + + if (e.isCancelled()) { + MsgUtil.sendMessage(p,MsgUtil.getMessage("no-permission", p)); + Util.debugLog("The action was cancelled by other plugin"); + return; + } + + if (!shop.getModerator().isOwner(p.getUniqueId()) + && !QuickShop.getPermissionManager().hasPermission(p, "quickshop.other.destroy")) { + e.setCancelled(true); + MsgUtil.sendMessage(p,MsgUtil.getMessage("no-permission", p)); + return; + } + // Cancel their current menu... Doesnt cancel other's menu's. + final Info action = super.getPlugin().getShopManager().getActions().get(p.getUniqueId()); + + if (action != null) { + action.setAction(ShopAction.CANCELLED); + } + + shop.onUnload(); + shop.delete(); + MsgUtil.sendMessage(p,MsgUtil.getMessage("success-removed-shop", p)); + } else if (Util.isWallSign(b.getType())) { + if (b.getState() instanceof Sign) { + Sign sign = (Sign) b.getState(); + if (sign.getLine(0).equals(super.getPlugin().getConfig().getString("lockette.private")) + || sign.getLine(0).equals(super.getPlugin().getConfig().getString("lockette.more_users"))) { + // Ignore break lockette sign + return; + } + } + + final Shop shop = getShopNextTo(b.getLocation()); + + if (shop == null) { + return; + } + // If they're in creative and not the owner, don't let them + // (accidents happen) + if (p.getGameMode() == GameMode.CREATIVE && !p.getUniqueId().equals(shop.getOwner())) { + // Check SuperTool + if (p.getInventory().getItemInMainHand().getType() == Material.GOLDEN_AXE) { + if(getPlugin().getConfig().getBoolean("shop.disable-super-tool")){ + e.setCancelled(true); + MsgUtil.sendMessage(p,MsgUtil.getMessage("supertool-is-disabled", p)); + return; + } + MsgUtil.sendMessage(p,MsgUtil.getMessage("break-shop-use-supertool", p)); + shop.delete(); + return; + } + e.setCancelled(true); + MsgUtil.sendMessage(p, + MsgUtil.getMessage( + "no-creative-break", p, MsgUtil.getItemi18n(Material.GOLDEN_AXE.name()))); + } + //Allow Shop owner break the shop sign(for sign replacement) + if(getPlugin().getConfig().getBoolean("shop.allow-owner-break-shop-sign")&&p.getUniqueId().equals(shop.getOwner())){ + return; + } + Util.debugLog("Cannot break the sign."); + e.setCancelled(true); + } + } + + /** + * Gets the shop a sign is attached to + * + * @param loc The location of the sign + * @return The shop + */ + @Nullable + private Shop getShopNextTo(@NotNull Location loc) { + final Block b = Util.getAttached(loc.getBlock()); + // Util.getAttached(b) + if (b == null) { + return null; + } + + return getShopPlayer(b.getLocation(), false); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onInventoryMove(InventoryMoveItemEvent event) { + if (!super.getPlugin().getConfig().getBoolean("shop.update-sign-when-inventory-moving", true)) { + return; + } + + final Inventory inventory = event.getDestination(); + final Location location = inventory.getLocation(); + + if (location == null) { + return; + } + + // Delayed task. Event triggers when item is moved, not when it is received. + final Shop shop = getShopRedstone(location, true); + if (shop != null) { + super.getPlugin().getSignUpdateWatcher().scheduleSignUpdate(shop); + } + } + + + /* + * Listens for chest placement, so a doublechest shop can't be created. + */ + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) + public void onPlace(BlockPlaceEvent e) { + + final Material type = e.getBlock().getType(); + final Block placingBlock = e.getBlock(); + final Player player = e.getPlayer(); + + if (type != Material.CHEST) { + return; + } + Block chest = null; + //Chest combine mechanic based checking + if (player.isSneaking()) { + Block blockAgainst = e.getBlockAgainst(); + if (blockAgainst.getType() == Material.CHEST && placingBlock.getFace(blockAgainst) != BlockFace.UP && placingBlock.getFace(blockAgainst) != BlockFace.DOWN && !(((Chest) blockAgainst.getState()).getInventory() instanceof DoubleChestInventory)) { + chest = e.getBlockAgainst(); + } else { + return; + } + } else { + //Get all chest in vertical Location + BlockFace placingChestFacing = ((Directional) (placingBlock.getState().getBlockData())).getFacing(); + for (BlockFace face : Util.getVerticalFacing()) { + //just check the right side and left side + if (face != placingChestFacing && face != placingChestFacing.getOppositeFace()) { + Block nearByBlock = placingBlock.getRelative(face); + if (nearByBlock.getType() == Material.CHEST + //non double chest + && !(((Chest) nearByBlock.getState()).getInventory() instanceof DoubleChestInventory) + //same facing + && placingChestFacing == ((Directional) nearByBlock.getState().getBlockData()).getFacing()) { + if (chest == null) { + chest = nearByBlock; + } else { + //when multiply chests competed, minecraft will always combine with right side + if (placingBlock.getFace(nearByBlock) == Util.getRightSide(placingChestFacing)) { + chest = nearByBlock; + } + } + } + } + } + } + if (chest == null) { + return; + } + + Shop shop = getShopPlayer(chest.getLocation(), false); + if (shop != null) { + if (!QuickShop.getPermissionManager().hasPermission(player, "quickshop.create.double")) { + e.setCancelled(true); + MsgUtil.sendMessage(player,MsgUtil.getMessage("no-double-chests", player)); + + } else if (!shop.getModerator().isModerator(player.getUniqueId())) { + e.setCancelled(true); + MsgUtil.sendMessage(player,MsgUtil.getMessage("not-managed-shop", player)); + } + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ChatListener.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ChatListener.java new file mode 100644 index 0000000..9c1530b --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ChatListener.java @@ -0,0 +1,56 @@ +/* + * This file is a part of project QuickShop, the name is ChatListener.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.J; + +import lombok.AllArgsConstructor; +import org.abc.A.QuickShop; +import org.abc.A.util.Util; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.jetbrains.annotations.NotNull; + +/** + * @author Netherfoam + */ +@AllArgsConstructor +public class ChatListener implements Listener { + + @NotNull + private final QuickShop plugin; + + @EventHandler(priority = EventPriority.LOWEST) + public void onChat(AsyncPlayerChatEvent e) { + + if (e.isCancelled() && plugin.getConfig().getBoolean("shop.ignore-cancel-chat-event")) { + Util.debugLog("Ignored a chat event (Canceled by another plugin.)"); + return; + } + + if (!plugin.getShopManager().getActions().containsKey(e.getPlayer().getUniqueId())) { + return; + } + // Fix stupid chat plugin will add a weird space before or after the number we want. + plugin.getShopManager().handleChat(e.getPlayer(), e.getMessage().trim()); + e.setCancelled(true); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ChunkListener.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ChunkListener.java new file mode 100644 index 0000000..497db2f --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ChunkListener.java @@ -0,0 +1,70 @@ +/* + * This file is a part of project QuickShop, the name is ChunkListener.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.J; + +import java.util.HashMap; +import lombok.AllArgsConstructor; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.world.ChunkLoadEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.jetbrains.annotations.NotNull; +import org.abc.A.QuickShop; +import org.abc.A.N.Shop; + +@AllArgsConstructor +public class ChunkListener implements Listener { + + @NotNull + private final QuickShop plugin; + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onChunkLoad(ChunkLoadEvent e) { + if (e.isNewChunk()) { + return; + } + final HashMap inChunk = plugin.getShopManager().getShops(e.getChunk()); + if (inChunk == null || inChunk.isEmpty()) { + return; + } + Bukkit.getScheduler().runTaskLater(plugin, () -> { + for (Shop shop : new HashMap<>(inChunk).values()) { + shop.onLoad(); + } + }, 1); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onChunkUnload(ChunkUnloadEvent e) { + + final HashMap inChunk = plugin.getShopManager().getShops(e.getChunk()); + + if (inChunk == null || inChunk.isEmpty()) { + return; + } + for (Shop shop : new HashMap<>(inChunk).values()) { + shop.onUnload(); + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ClearLaggListener.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ClearLaggListener.java new file mode 100644 index 0000000..64e3d04 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ClearLaggListener.java @@ -0,0 +1,53 @@ +/* + * This file is a part of project QuickShop, the name is ClearLaggListener.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.J; + +import java.util.ArrayList; +import java.util.List; + +import org.abc.A.util.Util; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Item; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.abc.A.N.DisplayItem; + +public class ClearLaggListener implements Listener { + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH) + public void plugin(me.minebuilders.clearlag.events.EntityRemoveEvent clearlaggEvent) { + final List entities = clearlaggEvent.getEntityList(); + final List pendingExclude = new ArrayList<>(); + + for (Entity entity : entities) { + if (!(entity instanceof Item) + || !DisplayItem.checkIsGuardItemStack(((Item) entity).getItemStack())) { + continue; + } + + pendingExclude.add(entity); + } + + pendingExclude.forEach(clearlaggEvent::removeEntity); + Util.debugLog("Prevent " + pendingExclude.size() + " displays removal by ClearLagg."); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/CustomInventoryListener.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/CustomInventoryListener.java new file mode 100644 index 0000000..69866a5 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/CustomInventoryListener.java @@ -0,0 +1,102 @@ +/* + * This file is a part of project QuickShop, the name is CustomInventoryListener.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.J; + +import lombok.AllArgsConstructor; +import org.bukkit.event.Event.Result; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.*; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.abc.A.QuickShop; +import org.abc.A.N.InventoryPreview; + +@AllArgsConstructor +public class CustomInventoryListener implements Listener { + + @NotNull + private final QuickShop plugin; + + @EventHandler(ignoreCancelled = true) + public void invEvent(InventoryInteractEvent e) { + + final Inventory inventory = e.getInventory(); + final ItemStack[] stacks = inventory.getContents(); + + for (ItemStack itemStack : stacks) { + if (!InventoryPreview.isPreviewItem(itemStack)) { + continue; + } + + e.setCancelled(true); + e.setResult(Result.DENY); + } + } + + @EventHandler(ignoreCancelled = true) + public void invEvent(InventoryMoveItemEvent e) { + + if (InventoryPreview.isPreviewItem(e.getItem())) { + e.setCancelled(true); + } + } + + @EventHandler + public void invEvent(InventoryClickEvent e) { + + if (InventoryPreview.isPreviewItem(e.getCursor())) { + e.setCancelled(true); + e.setResult(Result.DENY); + } + + if (InventoryPreview.isPreviewItem(e.getCurrentItem())) { + e.setCancelled(true); + e.setResult(Result.DENY); + } + } + + @EventHandler + public void invEvent(InventoryDragEvent e) { + + if (InventoryPreview.isPreviewItem(e.getCursor()) + || InventoryPreview.isPreviewItem(e.getOldCursor())) { + e.setCancelled(true); + e.setResult(Result.DENY); + } + } + + @EventHandler + public void invEvent(InventoryPickupItemEvent e) { + + final Inventory inventory = e.getInventory(); + final ItemStack[] stacks = inventory.getContents(); + + for (ItemStack itemStack : stacks) { + if (!InventoryPreview.isPreviewItem(itemStack)) { + continue; + } + + e.setCancelled(true); + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/DisplayBugFixListener.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/DisplayBugFixListener.java new file mode 100644 index 0000000..5bf0396 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/DisplayBugFixListener.java @@ -0,0 +1,65 @@ +/* + * This file is a part of project QuickShop, the name is DisplayBugFixListener.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.J; + +import java.util.Collection; +import lombok.AllArgsConstructor; +import org.abc.A.util.Util; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockCanBuildEvent; +import org.jetbrains.annotations.NotNull; +import org.abc.A.QuickShop; +import org.abc.A.N.DisplayItem; +import org.abc.A.N.DisplayType; + +@AllArgsConstructor +public class DisplayBugFixListener implements Listener { + + @NotNull + private final QuickShop plugin; + + @EventHandler(ignoreCancelled = true) + public void canBuild(BlockCanBuildEvent e) { + if (!plugin.isDisplay() + || DisplayItem.getNowUsing() != DisplayType.ARMORSTAND + || e.isBuildable()) { + return; + } + + final Collection entities = + e.getBlock().getWorld().getNearbyEntities(e.getBlock().getLocation(), 1.0, 1, 1.0); + + for (Entity entity : entities) { + if (!(entity instanceof ArmorStand) + || !DisplayItem.checkIsGuardItemStack(((ArmorStand) entity).getItemInHand())) { + continue; + } + + e.setBuildable(true); + Util.debugLog( + "Re-set the allowed build flag here because it found the cause of the display-item blocking it before."); + return; + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/DisplayProtectionListener.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/DisplayProtectionListener.java new file mode 100644 index 0000000..edbbbe3 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/DisplayProtectionListener.java @@ -0,0 +1,656 @@ +/* + * This file is a part of project QuickShop, the name is DisplayProtectionListener.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.J; + +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.Furnace; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Item; +import org.bukkit.event.Event.Result; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockPistonExtendEvent; +import org.bukkit.event.block.BlockPistonRetractEvent; +import org.bukkit.event.entity.*; +import org.bukkit.event.inventory.*; +import org.bukkit.event.player.PlayerArmorStandManipulateEvent; +import org.bukkit.event.player.PlayerBucketEmptyEvent; +import org.bukkit.event.player.PlayerFishEvent; +import org.bukkit.event.player.PlayerFishEvent.State; +import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.QuickShop; +import org.abc.A.N.DisplayItem; +import org.abc.A.N.DisplayType; +import org.abc.A.N.Shop; + +@SuppressWarnings("DuplicatedCode") +public class DisplayProtectionListener implements Listener { + private final QuickShop plugin; + + private final boolean useEnhanceProtection; + + public DisplayProtectionListener(QuickShop plugin) { + this.plugin = plugin; + useEnhanceProtection = plugin.getConfig().getBoolean("shop.enchance-display-protect"); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void block(BlockFromToEvent event) { + if (!useEnhanceProtection) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + Block targetBlock = event.getToBlock(); + Block shopBlock = targetBlock.getRelative(BlockFace.DOWN); + Shop shop = plugin.getShopManager().getShopIncludeAttached(shopBlock.getLocation()); + if (shop == null) { + return; + } + event.setCancelled(true); + if (shop.getDisplay() != null) { + shop.getDisplay().remove(); + } + sendAlert( + "[DisplayGuard] Liuqid " + + targetBlock.getLocation() + + " trying flow to top of shop, QuickShop already cancel it."); + } + + private void sendAlert(@NotNull String msg) { + if (!plugin.getConfig().getBoolean("send-display-item-protection-alert")) { + return; + } + MsgUtil.sendGlobalAlert(msg); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void portal(EntityPortalEvent event) { + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + if (!(event.getEntity() instanceof Item)) { + return; + } + if (DisplayItem.checkIsGuardItemStack(((Item) event.getEntity()).getItemStack())) { + event.setCancelled(true); + event.getEntity().remove(); + sendAlert( + "[DisplayGuard] Somebody want dupe the display by Portal at " + + event.getFrom() + + " , QuickShop already cancel it."); + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void block(BlockPistonExtendEvent event) { + if (!useEnhanceProtection) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + Block block = event.getBlock().getRelative(event.getDirection()).getRelative(BlockFace.DOWN); + Shop shop = plugin.getShopManager().getShopIncludeAttached(block.getLocation()); + if (shop != null) { + event.setCancelled(true); + sendAlert( + "[DisplayGuard] Piston " + + event.getBlock().getLocation() + + " trying push somethings on the shop top, QuickShop already cancel it."); + if (shop.getDisplay() != null) { + shop.getDisplay().remove(); + } + return; + } + for (Block oBlock : event.getBlocks()) { + Block otherBlock = oBlock.getRelative(event.getDirection()).getRelative(BlockFace.DOWN); + if (Util.canBeShop(otherBlock)) { + shop = plugin.getShopManager().getShopIncludeAttached(otherBlock.getLocation()); + if (shop != null) { + event.setCancelled(true); + sendAlert( + "[DisplayGuard] Piston " + + event.getBlock().getLocation() + + " trying push somethings on the shop top, QuickShop already cancel it."); + if (shop.getDisplay() != null) { + shop.getDisplay().remove(); + } + return; + } + } + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void block(BlockPistonRetractEvent event) { + if (!useEnhanceProtection) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + Block block = event.getBlock().getRelative(event.getDirection()).getRelative(BlockFace.DOWN); + Shop shop = plugin.getShopManager().getShopIncludeAttached(block.getLocation()); + if (shop != null) { + event.setCancelled(true); + sendAlert( + "[DisplayGuard] Piston " + + event.getBlock().getLocation() + + " trying pull somethings on the shop top, QuickShop already cancel it."); + if (shop.getDisplay() != null) { + shop.getDisplay().remove(); + } + return; + } + for (Block oBlock : event.getBlocks()) { + Block otherBlock = oBlock.getRelative(event.getDirection()).getRelative(BlockFace.DOWN); + if (Util.canBeShop(otherBlock)) { + shop = plugin.getShopManager().getShopIncludeAttached(otherBlock.getLocation()); + if (shop != null) { + event.setCancelled(true); + sendAlert( + "[DisplayGuard] Piston " + + event.getBlock().getLocation() + + " trying push somethings on the shop top, QuickShop already cancel it."); + if (shop.getDisplay() != null) { + shop.getDisplay().remove(); + } + return; + } + } + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void block(BrewingStandFuelEvent event) { + if (!useEnhanceProtection) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + ItemStack itemStack = event.getFuel(); + if (DisplayItem.checkIsGuardItemStack(itemStack)) { + event.setCancelled(true); + sendAlert( + "[DisplayGuard] Block " + + event.getBlock().getLocation() + + " trying fuel the BrewingStand with DisplayItem."); + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void block(FurnaceBurnEvent event) { + if (!useEnhanceProtection) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + ItemStack itemStack = event.getFuel(); + if (DisplayItem.checkIsGuardItemStack(itemStack)) { + event.setCancelled(true); + Block furnace = event.getBlock(); + if (furnace.getState() instanceof Furnace) { + Furnace furnace1 = (Furnace) furnace.getState(); + sendAlert( + "[DisplayGuard] Block " + + event.getBlock().getLocation() + + " trying burn with DisplayItem."); + Util.inventoryCheck(furnace1.getInventory()); + } + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void block(FurnaceSmeltEvent event) { + if (!useEnhanceProtection) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + ItemStack itemStack = event.getSource(); + if (DisplayItem.checkIsGuardItemStack(itemStack)) { + event.setCancelled(true); + Block furnace = event.getBlock(); + if (furnace.getState() instanceof Furnace) { + Furnace furnace1 = (Furnace) furnace.getState(); + sendAlert( + "[DisplayGuard] Block " + + event.getBlock().getLocation() + + " trying smelt with DisplayItem."); + Util.inventoryCheck(furnace1.getInventory()); + } + return; + } + itemStack = event.getResult(); + if (DisplayItem.checkIsGuardItemStack(itemStack)) { + event.setCancelled(true); + Block furnace = event.getBlock(); + if (furnace.getState() instanceof Furnace) { + Furnace furnace1 = (Furnace) furnace.getState(); + sendAlert( + "[DisplayGuard] Block " + + event.getBlock().getLocation() + + " trying smelt with DisplayItem."); + Util.inventoryCheck(furnace1.getInventory()); + } + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void entity(EntityPickupItemEvent e) { + if (!useEnhanceProtection) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + ItemStack stack = e.getItem().getItemStack(); + if (!DisplayItem.checkIsGuardItemStack(stack)) { + return; + } + e.setCancelled(true); + // You shouldn't be able to pick up that... + e.getItem().remove(); + sendAlert( + "[DisplayGuard] Entity " + + e.getEntity().getName() + + " # " + + e.getEntity().getLocation() + + " pickedup the displayItem, QuickShop already removed it."); + + Entity entity = e.getEntity(); + if (entity instanceof InventoryHolder) { + Util.inventoryCheck(((InventoryHolder) entity).getInventory()); + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void entity(EntityDamageEvent event) { + if (!(event.getEntity() instanceof ArmorStand)) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.ARMORSTAND) { + return; + } + if (!DisplayItem.checkIsGuardItemStack(((ArmorStand) event.getEntity()).getItemInHand())) { + return; + } + event.setCancelled(true); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void entity(EntityDeathEvent event) { + if (!useEnhanceProtection) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.ARMORSTAND) { + return; + } + if (!(event.getEntity() instanceof ArmorStand)) { + return; + } + if (!DisplayItem.checkIsGuardItemStack(((ArmorStand) event.getEntity()).getItemInHand())) { + return; + } + event.setDroppedExp(0); + event.getDrops().clear(); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void entity(EntityInteractEvent event) { + if (!useEnhanceProtection) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.ARMORSTAND) { + return; + } + if (!(event.getEntity() instanceof ArmorStand)) { + return; + } + if (!DisplayItem.checkIsGuardItemStack(((ArmorStand) event.getEntity()).getItemInHand())) { + return; + } + event.setCancelled(true); + Entity entity = event.getEntity(); + if (entity instanceof InventoryHolder) { + Util.inventoryCheck(((InventoryHolder) entity).getInventory()); + } + sendAlert( + "[DisplayGuard] Entity " + + event.getEntityType().name() + + " # " + + event.getEntity().getLocation() + + " trying interact the hold displayItem's entity."); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void inventory(InventoryOpenEvent event) { + Util.inventoryCheck(event.getInventory()); + } + + // @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + // public void inventory(InventoryMoveItemEvent event) { + // if (ListenerHelper.isDisabled(event.getClass())) { + // return; + // } + // try { + // ItemStack is = event.getItem(); + // if (DisplayItem.checkIsGuardItemStack(is)) { + // event.setCancelled(true); ; + // sendAlert("[DisplayGuard] Inventory " + event.getInitiator() + // .getLocation().toString() + " trying moving displayItem, QuickShop + // already removed it."); + // event.setItem(new ItemStack(Material.AIR)); + // Util.inventoryCheck(event.getDestination()); + // Util.inventoryCheck(event.getInitiator()); + // Util.inventoryCheck(event.getSource()); + // } + // } catch (Exception e) {} + // } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void inventory(InventoryClickEvent event) { + if (!useEnhanceProtection) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + if (!DisplayItem.checkIsGuardItemStack(event.getCurrentItem())) { + return; + } + if (event.getClickedInventory() == null) { + return; + } + if (event.getClickedInventory().getLocation() == null) { + return; + } + event.setCancelled(true); + + sendAlert( + "[DisplayGuard] Inventory " + + event.getClickedInventory().getHolder() + + " at" + + event.getClickedInventory().getLocation() + + " was clicked the displayItem, QuickShop already removed it."); + event.getCurrentItem().setAmount(0); + event.getCurrentItem().setType(Material.AIR); + event.setResult(Result.DENY); + Util.inventoryCheck(event.getInventory()); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void inventory(InventoryPickupItemEvent event) { + ItemStack itemStack = event.getItem().getItemStack(); + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + if (!DisplayItem.checkIsGuardItemStack(itemStack)) { + return; // We didn't care that + } + @Nullable Location loc = event.getInventory().getLocation(); + @Nullable InventoryHolder holder = event.getInventory().getHolder(); + event.setCancelled(true); + sendAlert( + "[DisplayGuard] Something " + + holder + + " at " + + loc + + " trying pickup the DisplayItem, you should teleport to that location and to check detail.."); + Util.inventoryCheck(event.getInventory()); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void inventory(InventoryDragEvent event) { + if (!useEnhanceProtection) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + ItemStack itemStack = event.getCursor(); + if (DisplayItem.checkIsGuardItemStack(itemStack)) { + event.setCancelled(true); + Util.inventoryCheck(event.getInventory()); + sendAlert( + "[DisplayGuard] Player " + + event.getWhoClicked().getName() + + " trying use DisplayItem crafting."); + return; + } + itemStack = event.getOldCursor(); + if (DisplayItem.checkIsGuardItemStack(itemStack)) { + event.setCancelled(true); + Util.inventoryCheck(event.getInventory()); + sendAlert( + "[DisplayGuard] Player " + + event.getWhoClicked().getName() + + " trying use DisplayItem crafting."); + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void inventory(InventoryCreativeEvent event) { + if (!useEnhanceProtection) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + ItemStack itemStack = event.getCursor(); + if (DisplayItem.checkIsGuardItemStack(itemStack)) { + event.setCancelled(true); + Util.inventoryCheck(event.getInventory()); + sendAlert( + "[DisplayGuard] Player " + + event.getWhoClicked().getName() + + " trying use DisplayItem crafting."); + return; + } + itemStack = event.getCurrentItem(); + if (DisplayItem.checkIsGuardItemStack(itemStack)) { + event.setCancelled(true); + Util.inventoryCheck(event.getInventory()); + sendAlert( + "[DisplayGuard] Player " + + event.getWhoClicked().getName() + + " trying use DisplayItem crafting."); + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void item(PlayerItemHeldEvent e) { + if (!useEnhanceProtection) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + ItemStack stack = e.getPlayer().getInventory().getItemInMainHand(); + ItemStack stackOffHand = e.getPlayer().getInventory().getItemInOffHand(); + if (DisplayItem.checkIsGuardItemStack(stack)) { + e.getPlayer().getInventory().setItemInMainHand(new ItemStack(Material.AIR, 0)); + // You shouldn't be able to pick up that... + sendAlert( + "[DisplayGuard] Player " + + e.getPlayer().getName() + + " helded the displayItem, QuickShop already cancelled and removed it."); + e.setCancelled(true); + Util.inventoryCheck(e.getPlayer().getInventory()); + } + if (DisplayItem.checkIsGuardItemStack(stackOffHand)) { + e.getPlayer().getInventory().setItemInOffHand(new ItemStack(Material.AIR, 0)); + // You shouldn't be able to pick up that... + sendAlert( + "[DisplayGuard] Player " + + e.getPlayer().getName() + + " helded the displayItem, QuickShop already cancelled and removed it."); + e.setCancelled(true); + Util.inventoryCheck(e.getPlayer().getInventory()); + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void item(ItemDespawnEvent event) { + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + ItemStack itemStack = event.getEntity().getItemStack(); + if (DisplayItem.checkIsGuardItemStack(itemStack)) { + event.setCancelled(true); + } + + // Util.debugLog("We canceled an Item from despawning because they are our display item."); + } + // Player can't interact the item entity... of course + // @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + // public void player(PlayerInteractEvent e) { + // if (ListenerHelper.isDisabled(e.getClass())) { + // return; + // } + // ItemStack stack = e.getItem(); + // if (!DisplayItem.checkIsGuardItemStack(stack)) { + // return; + // } + // stack.setType(Material.AIR); + // stack.setAmount(0); + // // You shouldn't be able to pick up that... + // e.setCancelled(true); + // sendAlert("[DisplayGuard] Player " + ((Player) e) + // .getName() + " using the displayItem, QuickShop already removed it."); + // Util.inventoryCheck(e.getPlayer().getInventory()); + // } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void player(CraftItemEvent event) { + if (!useEnhanceProtection) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + ItemStack itemStack; + itemStack = event.getCurrentItem(); + if (DisplayItem.checkIsGuardItemStack(itemStack)) { + event.setCancelled(true); + Util.inventoryCheck(event.getInventory()); + sendAlert( + "[DisplayGuard] Player " + + event.getWhoClicked().getName() + + " trying use DisplayItem crafting."); + return; + } + itemStack = event.getCursor(); + if (DisplayItem.checkIsGuardItemStack(itemStack)) { + event.setCancelled(true); + Util.inventoryCheck(event.getInventory()); + sendAlert( + "[DisplayGuard] Player " + + event.getWhoClicked().getName() + + " trying use DisplayItem crafting."); + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void player(PlayerFishEvent event) { + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + if (event.getState() != State.CAUGHT_ENTITY) { + return; + } + if (event.getCaught() == null) { + return; + } + if (event.getCaught().getType() != EntityType.DROPPED_ITEM) { + return; + } + Item item = (Item) event.getCaught(); + ItemStack is = item.getItemStack(); + if (!DisplayItem.checkIsGuardItemStack(is)) { + return; + } + // item.remove(); + event.getHook().remove(); + // event.getCaught().remove(); + event.setCancelled(true); + sendAlert( + "[DisplayGuard] Player " + + event.getPlayer().getName() + + " trying hook item use Fishing Rod, QuickShop already removed it."); + Util.inventoryCheck(event.getPlayer().getInventory()); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void player(PlayerBucketEmptyEvent event) { + if (!useEnhanceProtection) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + Block waterBlock = event.getBlockClicked().getRelative(event.getBlockFace()); + Shop shop = + plugin.getShopManager().getShop(waterBlock.getRelative(BlockFace.DOWN).getLocation()); + if (shop == null) { + return; + } + event.setCancelled(true); + sendAlert( + "[DisplayGuard] Player " + + event.getPlayer().getName() + + " trying use water to move somethings on the shop top, QuickShop already remove it."); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void player(PlayerArmorStandManipulateEvent event) { + if (!DisplayItem.checkIsGuardItemStack(event.getArmorStandItem())) { + return; + } + if (DisplayItem.getNowUsing() != DisplayType.REALITEM) { + return; + } + event.setCancelled(true); + Util.inventoryCheck(event.getPlayer().getInventory()); + sendAlert( + "[DisplayGuard] Player " + + event.getPlayer().getName() + + " trying mainipulate armorstand contains displayItem."); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/LockListener.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/LockListener.java new file mode 100644 index 0000000..a9571ee --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/LockListener.java @@ -0,0 +1,235 @@ +/* + * This file is a part of project QuickShop, the name is LockListener.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.J; + +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryDragEvent; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.event.inventory.InventoryPickupItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.Cache; +import org.abc.A.QuickShop; +import org.abc.A.N.InventoryPreview; +import org.abc.A.N.Shop; + +public class LockListener extends ProtectionListenerBase implements Listener { + + public LockListener(@NotNull final QuickShop plugin, @Nullable final Cache cache) { + super(plugin, cache); + } + + @EventHandler(ignoreCancelled = true) + public void invEvent(InventoryMoveItemEvent e) { + if (!InventoryPreview.isPreviewItem(e.getItem())) { + return; + } + + e.setCancelled(true); + } + + @EventHandler + public void invEvent(InventoryClickEvent e) { + if (InventoryPreview.isPreviewItem(e.getCursor())) { + e.setCancelled(true); + e.setResult(Event.Result.DENY); + return; + } + + if (InventoryPreview.isPreviewItem(e.getCurrentItem())) { + e.setCancelled(true); + e.setResult(Event.Result.DENY); + } + } + + @EventHandler + public void invEvent(InventoryDragEvent e) { + if (InventoryPreview.isPreviewItem(e.getCursor())) { + e.setCancelled(true); + e.setResult(Event.Result.DENY); + return; + } + + if (InventoryPreview.isPreviewItem(e.getOldCursor())) { + e.setCancelled(true); + e.setResult(Event.Result.DENY); + } + } + + @EventHandler + public void invEvent(InventoryPickupItemEvent e) { + final Inventory inventory = e.getInventory(); + final ItemStack[] stacks = inventory.getContents(); + + for (ItemStack itemStack : stacks) { + if (itemStack == null) { + continue; + } + + if (InventoryPreview.isPreviewItem(itemStack)) { + e.setCancelled(true); + return; + } + } + } + + /* + * Removes chests when they're destroyed. + */ + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onBreak(BlockBreakEvent e) { + Block b = e.getBlock(); + + if (b.getState() instanceof Sign) { + final Sign sign = (Sign) b.getState(); + + if (sign.getLine(0).equals(super.getPlugin().getConfig().getString("lockette.private")) + || sign.getLine(0).equals(super.getPlugin().getConfig().getString("lockette.more_users"))) { + // Ignore break lockette sign + super.getPlugin().getLogger() + .info("Skipped a dead-lock shop sign.(Lockette or other sign-lock plugin)"); + return; + } + } + + final Player p = e.getPlayer(); + // If the chest was a chest + if (Util.canBeShop(b)) { + final Shop shop = getShopPlayer(b.getLocation(), true); + + if (shop == null) { + return; // Wasn't a shop + } + // If they owned it or have bypass perms, they can destroy it + if (!shop.getOwner().equals(p.getUniqueId()) + && !QuickShop.getPermissionManager().hasPermission(p, "quickshop.other.destroy")) { + e.setCancelled(true); + MsgUtil.sendMessage(p,MsgUtil.getMessage("no-permission", p)); + } + } else if (Util.isWallSign(b.getType())) { + if (b instanceof Sign) { + final Sign sign = (Sign) b; + + if (sign.getLine(0).equals(super.getPlugin().getConfig().getString("lockette.private")) + || sign.getLine(0).equals(super.getPlugin().getConfig().getString("lockette.more_users"))) { + // Ignore break lockette sign + return; + } + } + b = Util.getAttached(b); + + if (b == null) { + return; + } + + final Shop shop = getShopPlayer(b.getLocation(), false); + + if (shop == null) { + return; + } + // If they're the shop owner or have bypass perms, they can destroy + // it. + if (!shop.getOwner().equals(p.getUniqueId()) + && !QuickShop.getPermissionManager().hasPermission(p, "quickshop.other.destroy")) { + e.setCancelled(true); + MsgUtil.sendMessage(p,MsgUtil.getMessage("no-permission", p)); + } + } + } + + @EventHandler(ignoreCancelled = true) + public void onClick(PlayerInteractEvent e) { + + final Block b = e.getClickedBlock(); + + if (b == null) { + return; + } + + if (!Util.canBeShop(b)) { + return; + } + + final Player p = e.getPlayer(); + + if (e.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; // Didn't right click it, we dont care. + } + + final Shop shop = getShopPlayer(b.getLocation(), true); + // Make sure they're not using the non-shop half of a double chest. + if (shop == null) { + return; + } + + if (!shop.getModerator().isModerator(p.getUniqueId())) { + if (QuickShop.getPermissionManager().hasPermission(p, "quickshop.other.open")) { + MsgUtil.sendMessage(p,MsgUtil.getMessage("bypassing-lock", p)); + return; + } + MsgUtil.sendMessage(p,MsgUtil.getMessage("that-is-locked", p)); + e.setCancelled(true); + } + } + + /* + * Handles hopper placement + */ + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onPlace(BlockPlaceEvent e) { + + final Block b = e.getBlock(); + + if (b.getType() != Material.HOPPER) { + return; + } + + final Player p = e.getPlayer(); + + if (!Util.isOtherShopWithinHopperReach(b, p)) { + return; + } + + if (QuickShop.getPermissionManager().hasPermission(p, "quickshop.other.open")) { + MsgUtil.sendMessage(p,MsgUtil.getMessage("bypassing-lock", p)); + return; + } + + MsgUtil.sendMessage(p,MsgUtil.getMessage("that-is-locked", p)); + e.setCancelled(true); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/PlayerListener.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/PlayerListener.java new file mode 100644 index 0000000..9f237d1 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/PlayerListener.java @@ -0,0 +1,380 @@ +/* + * This file is a part of project QuickShop, the name is PlayerListener.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.J; + +import java.util.HashMap; +import java.util.Objects; +import java.util.UUID; +import lombok.AllArgsConstructor; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Event.Result; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.player.*; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.BlockIterator; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.F.Economy; +import org.abc.A.QuickShop; +import org.abc.A.N.Info; +import org.abc.A.N.Shop; +import org.abc.A.N.ShopAction; +import org.abc.A.N.ShopLoader; + +@AllArgsConstructor +public class PlayerListener implements Listener { + + @NotNull + private final QuickShop plugin; + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onClick(PlayerInteractEvent e) { + + if (!e.getAction().equals(Action.LEFT_CLICK_BLOCK) && e.getClickedBlock() != null) { + if (e.getAction().equals(Action.RIGHT_CLICK_BLOCK) + && Util.isWallSign(e.getClickedBlock().getType())) { + final Block block; + + if (Util.isWallSign(e.getClickedBlock().getType())) { + block = Util.getAttached(e.getClickedBlock()); + } else { + block = e.getClickedBlock(); + } + + if (plugin.getShopManager().getShop(Objects.requireNonNull(block).getLocation()) != null + && (Objects.requireNonNull(plugin.getShopManager().getShop(block.getLocation())) + .getOwner() + .equals(e.getPlayer().getUniqueId()) + || e.getPlayer().isOp())) { + if (plugin.getConfig().getBoolean("shop.sneak-to-control") + && !e.getPlayer().isSneaking()) { + return; + } + + if (plugin.getConfig().getBoolean("effect.sound.onclick")) { + e.getPlayer() + .playSound(e.getPlayer().getLocation(), Sound.BLOCK_DISPENSER_FAIL, 80.f, 1.0f); + } + + MsgUtil.sendControlPanelInfo( + e.getPlayer(), + Objects.requireNonNull(plugin.getShopManager().getShop(block.getLocation()))); + Objects.requireNonNull(plugin.getShopManager().getShop(block.getLocation())) + .setSignText(); + } + } + + return; + } + + final Block b = e.getClickedBlock(); + + if (b == null) { + return; + } + + if (!Util.canBeShop(b) && !Util.isWallSign(b.getType())) { + return; + } + + final Player p = e.getPlayer(); + final Location loc = b.getLocation(); + final ItemStack item = e.getItem(); + // Get the shop + Shop shop = plugin.getShopManager().getShop(loc); + // If that wasn't a shop, search nearby shops + if (shop == null) { + final Block attached; + + if (Util.isWallSign(b.getType())) { + attached = Util.getAttached(b); + + if (attached != null) { + shop = plugin.getShopManager().getShop(attached.getLocation()); + } + } else if (Util.isDoubleChest(b)) { + attached = Util.getSecondHalf(b); + + if (attached != null) { + Shop secondHalfShop = plugin.getShopManager().getShop(attached.getLocation()); + if (secondHalfShop != null && !p.getUniqueId().equals(secondHalfShop.getOwner())) { + // If player not the owner of the shop, make him select the second half of the + // shop + // Otherwise owner will be able to create new double chest shop + shop = secondHalfShop; + } + } + } + } + // Purchase handling + if (shop != null && QuickShop.getPermissionManager().hasPermission(p, "quickshop.use")) { + if (plugin.getConfig().getBoolean("shop.sneak-to-trade") && !p.isSneaking()) { + return; + } + + shop.onClick(); + + if (plugin.getConfig().getBoolean("effect.sound.onclick")) { + e.getPlayer() + .playSound(e.getPlayer().getLocation(), Sound.BLOCK_DISPENSER_FAIL, 80.f, 1.0f); + } + // Text menu + MsgUtil.sendShopInfo(p, shop); + shop.setSignText(); + + final Economy eco = plugin.getEconomy(); + final double price = shop.getPrice(); + final double money = plugin.getEconomy().getBalance(p.getUniqueId()); + + if (shop.isSelling()) { + int itemAmount = + Math.min( + Util.countSpace(p.getInventory(), shop.getItem()), (int) Math.floor(money / price)); + + if (!shop.isUnlimited()) { + itemAmount = Math.min(itemAmount, shop.getRemainingStock()); + } + + if (itemAmount < 0) { + itemAmount = 0; + } + + MsgUtil.sendMessage(p,MsgUtil.getMessage("how-many-buy", p, "" + itemAmount)); + } else { + final double ownerBalance = eco.getBalance(shop.getOwner()); + int items = Util.countItems(p.getInventory(), shop.getItem()); + final int ownerCanAfford = (int) (ownerBalance / shop.getPrice()); + + if (!shop.isUnlimited()) { + // Amount check player amount and shop empty slot + items = Math.min(items, shop.getRemainingSpace()); + // Amount check player selling item total cost and the shop owner's balance + items = Math.min(items, ownerCanAfford); + } else if (plugin.getConfig().getBoolean("shop.pay-unlimited-shop-owners")) { + // even if the shop is unlimited, the config option pay-unlimited-shop-owners is set to + // true, + // the unlimited shop owner should have enough money. + items = Math.min(items, ownerCanAfford); + } + + if (items < 0) { + items = 0; + } + + MsgUtil.sendMessage(p,MsgUtil.getMessage("how-many-sell", p, "" + items)); + } + // Add the new action + HashMap actions = plugin.getShopManager().getActions(); + Info info = new Info(shop.getLocation(), ShopAction.BUY, null, null, shop); + actions.put(p.getUniqueId(), info); + } + // Handles creating shops + else if (e.useInteractedBlock() == Result.ALLOW + && shop == null + && item != null + && item.getType() != Material.AIR + && QuickShop.getPermissionManager().hasPermission(p, "quickshop.create.sell") + && p.getGameMode() != GameMode.CREATIVE) { + if (e.useInteractedBlock() == Result.DENY + || plugin.getConfig().getBoolean("shop.sneak-to-create") && !p.isSneaking() + || !plugin.getShopManager().canBuildShop(p, b, e.getBlockFace())){ + // As of the new checking system, most plugins will tell the + // player why they can't create a shop there. + // So telling them a message would cause spam etc. + return; + } + + if (Util.getSecondHalf(b) != null + && !QuickShop.getPermissionManager().hasPermission(p, "quickshop.create.double")) { + MsgUtil.sendMessage(p,MsgUtil.getMessage("no-double-chests", p)); + return; + } + + if (Util.isBlacklisted(item) + && !QuickShop.getPermissionManager() + .hasPermission(p, "quickshop.bypass." + item.getType().name())) { + MsgUtil.sendMessage(p,MsgUtil.getMessage("blacklisted-item", p)); + return; + } + + if (b.getType() == Material.ENDER_CHEST + && !QuickShop.getPermissionManager().hasPermission(p, "quickshop.create.enderchest")) { + return; + } + /*if (!Util.canBeShop(b)) { + Util.debugLog("Can be shop check failed."); + return; + } + Already checked above*/ + + if (Util.isWallSign(b.getType())) { +// Util.debugLog("WallSign check failed."); + return; + } + // Finds out where the sign should be placed for the shop + Block last = null; + final Location from = p.getLocation().clone(); + + from.setY(b.getY()); + from.setPitch(0); + final BlockIterator bIt = new BlockIterator(from, 0, 7); + + while (bIt.hasNext()) { + final Block n = bIt.next(); + + if (n.equals(b)) { + break; + } + + last = n; + } + // Send creation menu. + final Info info = new Info(b.getLocation(), ShopAction.CREATE, e.getItem(), last); + + plugin.getShopManager().getActions().put(p.getUniqueId(), info); + MsgUtil.sendMessage(p, + MsgUtil.getMessage( + "how-much-to-trade-for", + p, + Util.getItemStackName(Objects.requireNonNull(e.getItem())))); + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onChat(AsyncPlayerChatEvent e) { + if(e.getMessage().startsWith("qsm")) + e.setCancelled(true); + ShopLoader.loadShop(e.getPlayer(), e.getMessage().trim()); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onInventoryClose(InventoryCloseEvent e) { + + @Nullable Inventory inventory = e.getInventory(); // Possibly wrong tag + @Nullable Location location = null; + + try { + // This will cause NPE when the internal getLocation method + // itself NPE, which should be a server issue. + location = inventory.getLocation(); + } catch (NullPointerException npe) { + return; // ignored as workaround, GH-303 + } + + if (location == null) { + return; + } + + final Shop shop = plugin.getShopManager().getShopIncludeAttached(location); + + if (shop != null) { + shop.setSignText(); + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onJoin(PlayerJoinEvent e) { + + // Notify the player any messages they were sent + if (plugin.getConfig().getBoolean("shop.auto-fetch-shop-messages")) { + MsgUtil.flush(e.getPlayer()); + } + } + + @EventHandler(ignoreCancelled = true) + public void onPlayerQuit(PlayerQuitEvent e) { + + // Remove them from the menu + plugin.getShopManager().getActions().remove(e.getPlayer().getUniqueId()); + } + + @EventHandler(ignoreCancelled = true) + public void onTeleport(PlayerTeleportEvent e) { + + PlayerMoveEvent me = new PlayerMoveEvent(e.getPlayer(), e.getFrom(), e.getTo()); + onMove(me); + } + + /* + * Waits for a player to move too far from a shop, then cancels the menu. + */ + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onMove(PlayerMoveEvent e) { + + final Info info = plugin.getShopManager().getActions().get(e.getPlayer().getUniqueId()); + + if (info == null) { + return; + } + + final Player p = e.getPlayer(); + final Location loc1 = info.getLocation(); + final Location loc2 = p.getLocation(); + + if (loc1.getWorld() != loc2.getWorld() || loc1.distanceSquared(loc2) > 25) { + if (info.getAction() == ShopAction.CREATE) { + MsgUtil.sendMessage(p,MsgUtil.getMessage("shop-creation-cancelled", p)); + Util.debugLog(p.getName() + " too far with the shop location."); + } else if (info.getAction() == ShopAction.BUY) { + MsgUtil.sendMessage(p,MsgUtil.getMessage("shop-purchase-cancelled", p)); + Util.debugLog(p.getName() + " too far with the shop location."); + } + plugin.getShopManager().getActions().remove(p.getUniqueId()); + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onDyeing(PlayerInteractEvent e) { + if (e.getAction() != Action.RIGHT_CLICK_BLOCK + || e.getItem() == null + || !Util.isDyes(e.getItem().getType())) { + return; + } + + final Block block = e.getClickedBlock(); + + if (block == null || !Util.isWallSign(block.getType())) { + return; + } + + final Block attachedBlock = Util.getAttached(block); + + if (attachedBlock == null + || plugin.getShopManager().getShopIncludeAttached(attachedBlock.getLocation()) == null) { + return; + } + + e.setCancelled(true); + Util.debugLog("Disallow " + e.getPlayer().getName() + " dye the shop sign."); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ProtectionListenerBase.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ProtectionListenerBase.java new file mode 100644 index 0000000..d9ef472 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ProtectionListenerBase.java @@ -0,0 +1,68 @@ +package org.abc.A.J; + +import lombok.Getter; +import org.bukkit.Location; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.Cache; +import org.abc.A.QuickShop; +import org.abc.A.N.Shop; + +@Getter +public class ProtectionListenerBase { + private QuickShop plugin; + + private Cache cache; + + public ProtectionListenerBase(@NotNull QuickShop plugin, @Nullable Cache cache) { + this.cache = cache; + this.plugin = plugin; + } + + /** + * Get shop for redstone events, will caching if caching enabled + * + * @param location The block location + * @param includeAttached whether to include the attached shop + * @return The shop object + */ + @SuppressWarnings("SpellCheckingInspection") + @Nullable + public Shop getShopRedstone(@NotNull Location location, boolean includeAttached) { + if (cache == null) { + if (includeAttached) { + return plugin.getShopManager().getShopIncludeAttached(location); + } else { + return plugin.getShopManager().getShop(location); + } + } + return cache.getCaching(location, includeAttached); + } + + /** + * Get shop for player events, won't be caching + * + * @param location The block location + * @param includeAttached whether to include the attached shop + * + * @return The shop object + */ + @Nullable + public Shop getShopPlayer(@NotNull Location location, boolean includeAttached) { + return includeAttached ? plugin.getShopManager().getShopIncludeAttached(location,false):plugin.getShopManager().getShop(location); + } + + /** + * Get shop for nature events, may will caching but usually it doesn't will cached. + * Because nature events usually won't check same block twice in shore time. + * + * @param location The block location + * @param includeAttached whether to include the attached shop + * @return The shop object + */ + @Nullable + public Shop getShopNature(@NotNull Location location, boolean includeAttached) { + return includeAttached ? plugin.getShopManager().getShopIncludeAttached(location,false):plugin.getShopManager().getShop(location); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ShopProtectionListener.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ShopProtectionListener.java new file mode 100644 index 0000000..18281a2 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/ShopProtectionListener.java @@ -0,0 +1,271 @@ +/* + * This file is a part of project QuickShop, the name is ShopProtectionListener.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.J; + +import java.util.AbstractMap; +import java.util.List; +import java.util.Map; + +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Entity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.*; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.event.world.StructureGrowEvent; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.Cache; +import org.abc.A.QuickShop; +import org.abc.A.N.Shop; + +@SuppressWarnings("DuplicatedCode") +public class ShopProtectionListener extends ProtectionListenerBase implements Listener { + + @NotNull + private final QuickShop plugin; + + private final boolean useEnhanceProtection; + + private final boolean sendProtectionAlert = QuickShop.instance.getConfig().getBoolean("send-shop-protection-alert", false); + + // Protect Minecart steal shop + Map.Entry lastInventoryMoveItemCheck = + new AbstractMap.SimpleEntry<>(null, null); + + public ShopProtectionListener(@NotNull QuickShop plugin, @Nullable Cache cache) { + super(plugin, cache); + this.plugin = plugin; + useEnhanceProtection = plugin.getConfig().getBoolean("shop.enchance-shop-protect"); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockExplode(BlockExplodeEvent e) { + + for (int i = 0; i < e.blockList().size(); i++) { + final Block b = e.blockList().get(i); + Shop shop = getShopNature(b.getLocation(), true); + if (shop == null) { + shop = getShopNextTo(b.getLocation()); + } + if (shop != null) { + if (plugin.getConfig().getBoolean("protect.explode")) { + e.setCancelled(true); + } else { + shop.delete(); + } + } + } + } + + /** + * Gets the shop a sign is attached to + * + * @param loc The location of the sign + * @return The shop + */ + @Nullable + private Shop getShopNextTo(@NotNull Location loc) { + final Block b = Util.getAttached(loc.getBlock()); + // Util.getAttached(b) + if (b == null) { + return null; + } + + return getShopNature(b.getLocation(), false); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockFromTo(BlockFromToEvent e) { + if (!useEnhanceProtection) { + return; + } + + final Shop shop = getShopNature(e.getToBlock().getLocation(), true); + + if (shop == null) { + return; + } + + e.setCancelled(true); + } + + // Protect Redstone active shop + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockRedstoneChange(BlockRedstoneEvent event) { + if (!useEnhanceProtection) { + return; + } + + final Shop shop = getShopRedstone(event.getBlock().getLocation(), true); + + if (shop == null) { + return; + } + + event.setNewCurrent(event.getOldCurrent()); + // plugin.getLogger().warning("[Exploit Alert] a Redstone tried to active of " + shop); + // Util.debugLog(ChatColor.RED + "[QuickShop][Exploit alert] Redstone was activated on the + // following shop " + shop); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockSpread(BlockSpreadEvent e) { + if (!useEnhanceProtection) { + return; + } + + final Block newBlock = e.getNewState().getBlock(); + final Shop thisBlockShop = getShopNature(newBlock.getLocation(), true); + final Shop underBlockShop = + getShopNature(newBlock.getRelative(BlockFace.DOWN).getLocation(), true); + + if (thisBlockShop == null && underBlockShop == null) { + return; + } + e.setCancelled(true); + } + + /* + * Handles shops breaking through explosions + */ + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onExplode(EntityExplodeEvent e) { + + for (int i = 0; i < e.blockList().size(); i++) { + final Block b = e.blockList().get(i); + final Shop shop = getShopNature(b.getLocation(), true); + + if (shop == null) { + continue; + } + if (plugin.getConfig().getBoolean("protect.explode")) { + e.setCancelled(true); + } else { + shop.delete(); + } + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH) + public void onInventoryMove(InventoryMoveItemEvent event) { + if (!plugin.getConfig().getBoolean("protect.hopper")) { + return; + } + final Location loc = event.getSource().getLocation(); + + if (loc == null) { + return; + } + final Shop shop = getShopRedstone(loc, true); + + if (shop == null) { + return; + } + + event.setCancelled(true); + + final Location location = event.getInitiator().getLocation(); + + if (location == null) { + return; + } + + final InventoryHolder holder = event.getInitiator().getHolder(); + + if (holder instanceof Entity) { + ((Entity) holder).remove(); + } else if (holder instanceof Block) { + location.getBlock().breakNaturally(); + } else { + Util.debugLog("Unknown location = " + loc); + } + + if (sendProtectionAlert) { + MsgUtil.sendGlobalAlert("[DisplayGuard] Defened a item steal action at" + location); + } + } + + // Protect Entity pickup shop + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onMobChangeBlock(EntityChangeBlockEvent event) { + if (!useEnhanceProtection) { + return; + } + + final Shop shop = getShopNature(event.getBlock().getLocation(), true); + + if (shop == null) { + return; + } + + if (plugin.getConfig().getBoolean("protect.entity")) { + event.setCancelled(true); + return; + } + + shop.delete(); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onStructureGrow(StructureGrowEvent event) { + if (!useEnhanceProtection) { + return; + } + + for (BlockState blockstate : event.getBlocks()) { + final Shop shop = getShopNature(blockstate.getLocation(), true); + + if (shop == null) { + continue; + } + + event.setCancelled(true); + return; + // plugin.getLogger().warning("[Exploit Alert] a StructureGrowing tried to break the shop of " + // + shop); + // Util.sendMessageToOps(ChatColor.RED + "[QuickShop][Exploit alert] A StructureGrowing tried + // to break the shop of " + shop); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onSpongeing(SpongeAbsorbEvent event) { + if (!useEnhanceProtection) { + return; + } + List blocks = event.getBlocks(); + for (BlockState block : blocks) { + if (getShopNature(block.getLocation(), true) != null) { + event.setCancelled(true); + } + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/WorldListener.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/WorldListener.java new file mode 100644 index 0000000..dd6e438 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/J/WorldListener.java @@ -0,0 +1,116 @@ +/* + * This file is a part of project QuickShop, the name is WorldListener.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.J; + +import java.util.HashMap; +import java.util.Map.Entry; +import lombok.AllArgsConstructor; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.world.WorldLoadEvent; +import org.bukkit.event.world.WorldUnloadEvent; +import org.jetbrains.annotations.NotNull; +import org.abc.A.QuickShop; +import org.abc.A.N.Shop; +import org.abc.A.N.ShopChunk; + +@AllArgsConstructor +public class WorldListener implements Listener { + + @NotNull + private final QuickShop plugin; + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onWorldLoad(WorldLoadEvent e) { + /* ************************************* + * This listener fixes any broken world references. Such as hashmap + * lookups will fail, because the World reference is different, but the + * world value is the same. + * ************************************ + */ + final World world = e.getWorld(); + + plugin.getShopLoader().loadShops(world.getName()); + // New world data + final HashMap> inWorld = new HashMap<>(1); + // Old world data + final HashMap> oldInWorld = + plugin.getShopManager().getShops(world.getName()); + // Nothing in the old world, therefore we don't care. No locations to + // update. + if (oldInWorld == null) { + return; + } + + for (Entry> oldInChunk : oldInWorld.entrySet()) { + final HashMap inChunk = new HashMap<>(1); + // Put the new chunk were the old chunk was + inWorld.put(oldInChunk.getKey(), inChunk); + + for (Entry entry : oldInChunk.getValue().entrySet()) { + final Shop shop = entry.getValue(); + + shop.getLocation().setWorld(world); + inChunk.put(shop.getLocation(), shop); + } + } + // Done - Now we can store the new world dataz! + + plugin.getShopManager().getShops().put(world.getName(), inWorld); + // This is a workaround, because I don't get parsed chunk events when a + // world first loads.... + // So manually tell all of these shops they're loaded. + for (Chunk chunk : world.getLoadedChunks()) { + final HashMap inChunk = plugin.getShopManager().getShops(chunk); + + if (inChunk == null || inChunk.isEmpty()) { + continue; + } + + for (Shop shop : inChunk.values()) { + shop.onLoad(); + } + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onWorldUnload(WorldUnloadEvent e) { + // FIXME: 24/11/2019 It's not necessary but ok. + // This is a workaround, because I don't get parsed chunk events when a + // world unloads, I think... + // So manually tell all of these shops they're unloaded. + for (Chunk chunk : e.getWorld().getLoadedChunks()) { + final HashMap inChunk = plugin.getShopManager().getShops(chunk); + + if (inChunk == null || inChunk.isEmpty()) { + continue; + } + + for (Shop shop : inChunk.values()) { + shop.onUnload(); + } + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/K/MckFileConfiguration.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/K/MckFileConfiguration.java new file mode 100644 index 0000000..b5a1a9e --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/K/MckFileConfiguration.java @@ -0,0 +1,25 @@ +package org.abc.A.K; + +import lombok.ToString; +import org.bukkit.configuration.file.FileConfiguration; +import org.jetbrains.annotations.NotNull; + +@ToString +public final class MckFileConfiguration extends FileConfiguration { + @NotNull + @Override + public String saveToString() { + return ""; + } + + @Override + public void loadFromString(@NotNull String s) { + } + + @NotNull + @Override + protected String buildHeader() { + return ""; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/JSONConfiguration.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/JSONConfiguration.java new file mode 100644 index 0000000..b0c637e --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/JSONConfiguration.java @@ -0,0 +1,195 @@ +package org.abc.A.L.com.dumbtruckman.JsonConfiguration; + +import com.google.gson.*; +import com.google.gson.internal.LinkedTreeMap; +import com.google.gson.reflect.TypeToken; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.Reader; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import org.apache.commons.lang.StringEscapeUtils; +import org.bukkit.Bukkit; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.FileConfiguration; +import org.jetbrains.annotations.NotNull; + +public final class JSONConfiguration extends FileConfiguration { + + protected static final String BLANK_CONFIG = "{}\n"; + + @NotNull + public static JSONConfiguration loadConfiguration(@NotNull File file) { + final JSONConfiguration config = new JSONConfiguration(); + + try { + config.load(file); + } catch (FileNotFoundException ignored) { + // ignored... + } catch (IOException | InvalidConfigurationException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, ex); + } + + return config; + } + + @NotNull + public static JSONConfiguration loadConfiguration(@NotNull Reader reader) { + final JSONConfiguration config = new JSONConfiguration(); + + try { + config.load(reader); + } catch (IOException | InvalidConfigurationException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Cannot load configuration from stream", ex); + } + + return config; + } + + @NotNull + @Override + public String saveToString() { + final GsonBuilder gsonBuilder = new GsonBuilder().disableHtmlEscaping(); + + // if (!options().prettyPrint()) { + gsonBuilder.setPrettyPrinting(); + // } + final Gson gson = gsonBuilder.create(); + final Object value = SerializationHelper.serialize(getValues(false)); + final String dump = StringEscapeUtils.unescapeJava(gson.toJson(value)); + + if (dump.equals(BLANK_CONFIG)) { + return ""; + } + + return dump; + } + + @Override + public void loadFromString(@NotNull String contents) throws InvalidConfigurationException { + if (contents.isEmpty()) { + return; + } + + final Map input; + + try { + final Gson gson = + new GsonBuilder() + .registerTypeAdapter( + new TypeToken>() { + }.getType(), + new MapDeserializerDoubleAsIntFix()) + .create(); + input = gson.fromJson(contents, new TypeToken>() { + }.getType()); + } catch (JsonSyntaxException e) { + throw new InvalidConfigurationException("Invalid JSON detected.", e); + } catch (ClassCastException e) { + throw new InvalidConfigurationException("Top level is not a Map.", e); + } + + if (input != null) { + convertMapsToSections(input, this); + } else { + throw new InvalidConfigurationException( + "An unknown error occurred while attempting to parse the json."); + } + } + + @NotNull + @Override + protected String buildHeader() { + return ""; + } + + @NotNull + @Override + public JSONConfigurationOptions options() { + if (options == null) { + options = new JSONConfigurationOptions(this); + } + + return (JSONConfigurationOptions) options; + } + + protected void convertMapsToSections( + @NotNull Map input, @NotNull ConfigurationSection section) { + final Object result = SerializationHelper.deserialize(input); + + if (result instanceof Map) { + input = (Map) result; + + for (Map.Entry entry : input.entrySet()) { + final String key = entry.getKey().toString(); + final Object value = entry.getValue(); + + if (value instanceof Map) { + convertMapsToSections((Map) value, section.createSection(key)); + } else { + section.set(key, value); + } + } + } else { + section.set("", result); + } + } + + public static class MapDeserializerDoubleAsIntFix + implements JsonDeserializer> { + + @Override + @SuppressWarnings("unchecked") + public Map deserialize( + JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + return (Map) read(json); + } + + public Object read(JsonElement in) { + + if (in.isJsonArray()) { + List list = new ArrayList<>(); + JsonArray arr = in.getAsJsonArray(); + for (JsonElement anArr : arr) { + list.add(read(anArr)); + } + return list; + } else if (in.isJsonObject()) { + Map map = new LinkedTreeMap<>(); + JsonObject obj = in.getAsJsonObject(); + Set> entitySet = obj.entrySet(); + for (Map.Entry entry : entitySet) { + map.put(entry.getKey(), read(entry.getValue())); + } + return map; + } else if (in.isJsonPrimitive()) { + JsonPrimitive prim = in.getAsJsonPrimitive(); + if (prim.isBoolean()) { + return prim.getAsBoolean(); + } else if (prim.isString()) { + return prim.getAsString(); + } else if (prim.isNumber()) { + Number num = prim.getAsNumber(); + // here you can handle double int/long values + // and return any type you want + // this solution will transform 3.0 float to long values + if (Math.ceil(num.doubleValue()) == num.longValue()) { + return num.longValue(); + } else { + return num.doubleValue(); + } + } + } + return null; + } + + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/JSONConfigurationOptions.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/JSONConfigurationOptions.java new file mode 100644 index 0000000..2a86851 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/JSONConfigurationOptions.java @@ -0,0 +1,66 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +package org.abc.A.L.com.dumbtruckman.JsonConfiguration; + +import org.bukkit.configuration.file.FileConfigurationOptions; +import org.jetbrains.annotations.NotNull; + +public class JSONConfigurationOptions extends FileConfigurationOptions { + + private boolean enablePrettyPrint = true; + + protected JSONConfigurationOptions(@NotNull final JSONConfiguration configuration) { + super(configuration); + } + + @Override + public JSONConfiguration configuration() { + return (JSONConfiguration) super.configuration(); + } + + @Override + public JSONConfigurationOptions copyDefaults(final boolean value) { + super.copyDefaults(value); + return this; + } + + @Override + public JSONConfigurationOptions pathSeparator(final char value) { + super.pathSeparator(value); + return this; + } + + @Override + public JSONConfigurationOptions header(final String value) { + super.header(value); + return this; + } + + @Override + public JSONConfigurationOptions copyHeader(final boolean value) { + super.copyHeader(value); + return this; + } + + /** + * Sets whether or not to pretty print the json output of the configuration. + * + * @param enable Whether or not pretty printing should be enabled. + * @return This object, for chaining. + */ + public JSONConfigurationOptions prettyPrint(final boolean enable) { + enablePrettyPrint = enable; + return this; + } + + /** + * Gets whether or not to pretty print the json output of the configuration. + * + * @return Whether or not to pretty print the json. + */ + public boolean prettyPrint() { + return enablePrettyPrint; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/SerializableSet.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/SerializableSet.java new file mode 100644 index 0000000..9f91a40 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/SerializableSet.java @@ -0,0 +1,151 @@ +package org.abc.A.L.com.dumbtruckman.JsonConfiguration; + +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.stream.Stream; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.SerializableAs; +import org.jetbrains.annotations.NotNull; + +@SerializableAs("set") +public class SerializableSet implements Set, ConfigurationSerializable { + + @NotNull + private final Set backingSet; + + public SerializableSet(@NotNull Set backingSet) { + this.backingSet = backingSet; + } + + @SuppressWarnings("unchecked") + public SerializableSet(@NotNull Map serializedForm) { + Object o = serializedForm.get("contents"); + if (o instanceof List) { + backingSet = new HashSet((List) o); + } else { + backingSet = Collections.emptySet(); + } + } + + @SuppressWarnings("unchecked") + @Override + public Map serialize() { + Map serializedForm = new HashMap<>(backingSet.size()); + List contents = new ArrayList(backingSet); + serializedForm.put("contents", contents); + return serializedForm; + } + + @Override + public int size() { + return backingSet.size(); + } + + @Override + public boolean isEmpty() { + return backingSet.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return backingSet.contains(o); + } + + @NotNull + @Override + public Iterator iterator() { + return backingSet.iterator(); + } + + @NotNull + @Override + public Object[] toArray() { + return backingSet.toArray(); + } + + @NotNull + @Override + public Object[] toArray(@NotNull Object[] a) { + return backingSet.toArray(a); + } + + @SuppressWarnings("unchecked") + @Override + public boolean add(Object o) { + return backingSet.add(o); + } + + @Override + public boolean remove(Object o) { + return backingSet.remove(o); + } + + @SuppressWarnings("unchecked") + @Override + public boolean containsAll(@NotNull Collection c) { + return backingSet.containsAll(c); + } + + @SuppressWarnings("unchecked") + @Override + public boolean addAll(@NotNull Collection c) { + return backingSet.addAll(c); + } + + @SuppressWarnings("unchecked") + @Override + public boolean retainAll(@NotNull Collection c) { + return backingSet.retainAll(c); + } + + @SuppressWarnings("unchecked") + @Override + public boolean removeAll(@NotNull Collection c) { + return backingSet.removeAll(c); + } + + @Override + public void clear() { + backingSet.clear(); + } + + @Override + public Spliterator spliterator() { + return backingSet.spliterator(); + } + + @Override + public int hashCode() { + return backingSet.hashCode(); + } + + @SuppressWarnings("EqualsWhichDoesntCheckParameterClass") + @Override + public boolean equals(Object o) { + return backingSet.equals(o); + } + + @SuppressWarnings("unchecked") + @Override + public boolean removeIf(Predicate filter) { + return backingSet.removeIf(filter); + } + + @Override + public Stream stream() { + return backingSet.stream(); + } + + @Override + public Stream parallelStream() { + return backingSet.parallelStream(); + } + + @SuppressWarnings("unchecked") + @Override + public void forEach(Consumer action) { + backingSet.forEach(action); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/SerializationHelper.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/SerializationHelper.java new file mode 100644 index 0000000..347191b --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/dumbtruckman/JsonConfiguration/SerializationHelper.java @@ -0,0 +1,170 @@ +/* + * This file is a part of project QuickShop, the name is SerializationHelper.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.L.com.dumbtruckman.JsonConfiguration; + +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.jetbrains.annotations.NotNull; +import org.yaml.snakeyaml.error.YAMLException; + +/** + * @author Jeremy Wood + * @version 6/14/2017 + */ +public class SerializationHelper { + + private static final Logger LOG = Logger.getLogger(SerializationHelper.class.getName()); + + public static Object serialize(@NotNull Object value) { + if (value instanceof Object[]) { + value = new ArrayList<>(Arrays.asList((Object[]) value)); + } + if (value instanceof Set && !(value instanceof SerializableSet)) { + value = new SerializableSet((Set) value); + } + if (value instanceof ConfigurationSection) { + return buildMap(((ConfigurationSection) value).getValues(false)); + } else if (value instanceof Map) { + return buildMap((Map) value); + } else if (value instanceof List) { + return buildList((List) value); + } else if (value instanceof ConfigurationSerializable) { + ConfigurationSerializable serializable = (ConfigurationSerializable) value; + Map values = new LinkedHashMap<>(); + values.put( + ConfigurationSerialization.SERIALIZED_TYPE_KEY, + ConfigurationSerialization.getAlias(serializable.getClass())); + values.putAll(serializable.serialize()); + return buildMap(values); + } else { + return value; + } + } + + /** + * Parses through the input map to deal with serialized objects a la {@link + * ConfigurationSerializable}. + * + *

Called recursively first on Maps and Lists before passing the parsed input over to {@link + * ConfigurationSerialization#deserializeObject(java.util.Map)}. Basically this means it will + * deserialize the most nested objects FIRST and the top level object LAST. + * + * @param input the input + * @return the object that deserialize + */ + public static Object deserialize(@NotNull final Map input) { + final Map output = new LinkedHashMap<>(input.size()); + for (final Map.Entry e : input.entrySet()) { + if (e.getValue() instanceof Map) { + output.put(e.getKey().toString(), deserialize((Map) e.getValue())); + } else if (e.getValue() instanceof List) { + output.put(e.getKey().toString(), deserialize((List) e.getValue())); + } else { + output.put(e.getKey().toString(), e.getValue()); + } + } + if (output.containsKey(ConfigurationSerialization.SERIALIZED_TYPE_KEY)) { + try { + return ConfigurationSerialization.deserializeObject(output); + } catch (IllegalArgumentException ex) { + throw new YAMLException("Could not deserialize object", ex); + } + } + return output; + } + + /** + * Takes a Map and parses through the values, to ensure that, before saving, all objects are as + * appropriate as possible for storage in most data formats. + * + *

Specifically it does the following: for Map: calls this method recursively on the Map before + * putting it in the returned Map. for List: calls {@link #buildList(java.util.Collection)} which + * functions similar to this method. for ConfigurationSection: gets the values as a map and calls + * this method recursively on the Map before putting it in the returned Map. for + * ConfigurationSerializable: add the {@link ConfigurationSerialization#SERIALIZED_TYPE_KEY} to a + * new Map along with the Map given by {@link + * org.bukkit.configuration.serialization.ConfigurationSerializable#serialize()} and calls this + * method recursively on the new Map before putting it in the returned Map. for Everything else: + * stores it as is in the returned Map. + */ + @NotNull + private static Map buildMap(@NotNull final Map map) { + final Map result = new LinkedHashMap<>(map.size()); + try { + for (final Map.Entry entry : map.entrySet()) { + result.put(entry.getKey().toString(), serialize(entry.getValue())); + } + } catch (final Exception e) { + LOG.log(Level.WARNING, "Error while building configuration map.", e); + } + return result; + } + + /** + * Takes a Collection and parses through the values, to ensure that, before saving, all objects + * are as appropriate as possible for storage in most data formats. + * + *

Specifically it does the following: for Map: calls {@link #buildMap(java.util.Map)} on the + * Map before adding to the returned list. for List: calls this method recursively on the List. + * for ConfigurationSection: gets the values as a map and calls {@link #buildMap(java.util.Map)} + * on the Map before adding to the returned list. for ConfigurationSerializable: add the {@link + * ConfigurationSerialization#SERIALIZED_TYPE_KEY} to a new Map along with the Map given by {@link + * org.bukkit.configuration.serialization.ConfigurationSerializable#serialize()} and calls {@link + * #buildMap(java.util.Map)} on the new Map before adding to the returned list. for Everything + * else: stores it as is in the returned List. + */ + private static List buildList(@NotNull final Collection collection) { + final List result = new ArrayList<>(collection.size()); + try { + for (Object o : collection) { + result.add(serialize(o)); + } + } catch (Exception e) { + LOG.log(Level.WARNING, "Error while building configuration list.", e); + } + return result; + } + + /** + * Parses through the input list to deal with serialized objects a la {@link + * ConfigurationSerializable}. + * + *

Functions similarly to {@link #deserialize(java.util.Map)} but only for detecting lists + * within lists and maps within lists. + */ + private static Object deserialize(@NotNull final List input) { + final List output = new ArrayList<>(input.size()); + for (final Object o : input) { + if (o instanceof Map) { + output.add(deserialize((Map) o)); + } else if (o instanceof List) { + output.add(deserialize((List) o)); + } else { + output.add(o); + } + } + return output; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/sk89q/worldedit/util/net/HttpRequest.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/sk89q/worldedit/util/net/HttpRequest.java new file mode 100644 index 0000000..7cbd64c --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/sk89q/worldedit/util/net/HttpRequest.java @@ -0,0 +1,500 @@ +package org.abc.A.L.com.sk89q.worldedit.util.net; +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +import com.google.common.io.Closer; +import java.io.*; +import java.net.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class HttpRequest implements Closeable { + + private static final int CONNECT_TIMEOUT = 1000 * 10; + + private static final int READ_TIMEOUT = 1000 * 17; + + private static final int READ_BUFFER_SIZE = 1024 * 8; + + private final Map headers = new HashMap<>(); + + private final String method; + + private final URL url; + + private String contentType; + + private byte[] body; + + private HttpURLConnection conn; + + private InputStream inputStream; + + // private long contentLength = -1; + private long readBytes = 0; + + /** + * Create a new HTTP request. + * + * @param method the method + * @param url the URL + */ + private HttpRequest(String method, URL url) { + this.method = method; + this.url = url; + } + + /** + * Perform a GET request. + * + * @param url the URL + * @return a new request object + */ + public static HttpRequest get(URL url) { + return request("GET", url); + } + + /** + * Perform a request. + * + * @param method the method + * @param url the URL + * @return a new request object + */ + public static HttpRequest request(String method, URL url) { + return new HttpRequest(method, url); + } + + /** + * Perform a POST request. + * + * @param url the URL + * @return a new request object + */ + public static HttpRequest post(URL url) { + return request("POST", url); + } + + /** + * Create a new {@link java.net.URL} and throw a {@link RuntimeException} if the URL is not valid. + * + * @param url the url + * @return a URL object + * @throws RuntimeException if the URL is invalid + */ + public static URL url(String url) { + try { + return new URL(url); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + /** + * Submit data. + * + * @param data the data + * @return this object + */ + public HttpRequest body(String data) { + body = data.getBytes(); + return this; + } + + /** + * Submit form data. + * + * @param form the form + * @return this object + */ + public HttpRequest bodyForm(Form form) { + contentType = "application/x-www-form-urlencoded"; + body = form.toString().getBytes(); + return this; + } + + /** + * Add a header. + * + * @param key the header key + * @param value the header value + * @return this object + */ + public HttpRequest header(String key, String value) { + if ("Content-Type".equalsIgnoreCase(key)) { + contentType = value; + } else { + headers.put(key, value); + } + return this; + } + + + /** + * Execute the request. + * + *

After execution, {@link #close()} should be called. + * + * @return this object + * @throws java.io.IOException on I/O error + */ + public HttpRequest execute() throws IOException { + return execute(-1); + } + + + /** + * Execute the request. + * + *

After execution, {@link #close()} should be called. + * + * @param timeout timeout + * @return this object + * @throws java.io.IOException on I/O error + */ + public HttpRequest execute(int timeout) throws IOException { + boolean successful = false; + + try { + if (conn != null) { + throw new IllegalArgumentException("Connection already executed"); + } + + conn = (HttpURLConnection) reformat(url).openConnection(); + conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Java)"); + + if (body != null) { + conn.setRequestProperty("Content-Type", contentType); + conn.setRequestProperty("Content-Length", Integer.toString(body.length)); + conn.setDoInput(true); + } + + for (Map.Entry entry : headers.entrySet()) { + conn.setRequestProperty(entry.getKey(), entry.getValue()); + } + + conn.setRequestMethod(method); + conn.setUseCaches(false); + conn.setDoOutput(true); + conn.setConnectTimeout(CONNECT_TIMEOUT); + if (timeout != -1) { + conn.setReadTimeout(timeout); + } else { + conn.setReadTimeout(READ_TIMEOUT); + } + + + conn.connect(); + + if (body != null) { + DataOutputStream out = new DataOutputStream(conn.getOutputStream()); + out.write(body); + out.flush(); + out.close(); + } + + inputStream = + conn.getResponseCode() == HttpURLConnection.HTTP_OK + ? conn.getInputStream() + : conn.getErrorStream(); + + successful = true; + } finally { + if (!successful) { + close(); + } + } + + return this; + } + + /** + * URL may contain spaces and other nasties that will cause a failure. + * + * @param existing the existing URL to transform + * @return the new URL, or old one if there was a failure + */ + private static URL reformat(URL existing) { + try { + URL url = new URL(existing.toString()); + URI uri = + new URI( + url.getProtocol(), + url.getUserInfo(), + url.getHost(), + url.getPort(), + url.getPath(), + url.getQuery(), + url.getRef()); + url = uri.toURL(); + return url; + } catch (MalformedURLException | URISyntaxException e) { + return existing; + } + } + + @Override + public void close() { + if (conn != null) { + conn.disconnect(); + } + } + + /** + * Require that the response code is one of the given response codes. + * + * @param codes a list of codes + * @return this object + * @throws java.io.IOException if there is an I/O error or the response code is not expected + */ + public HttpRequest expectResponseCode(int... codes) throws IOException { + int responseCode = getResponseCode(); + + for (int code : codes) { + if (code == responseCode) { + return this; + } + } + + close(); + throw new IOException( + "Did not get expected response code, got " + responseCode + " for " + url); + } + + /** + * Get the response code. + * + * @return the response code + * @throws java.io.IOException on I/O error + */ + public int getResponseCode() throws IOException { + if (conn == null) { + throw new IllegalArgumentException("No connection has been made"); + } + + return conn.getResponseCode(); + } + + /** + * Get the input stream. + * + * @return the input stream + */ + public InputStream getInputStream() { + return inputStream; + } + + /** + * Buffer the returned response. + * + * @return the buffered response + * @throws java.io.IOException on I/O error + */ + public BufferedResponse returnContent() throws IOException { + if (inputStream == null) { + throw new IllegalArgumentException("No input stream available"); + } + + try { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + int b; + while ((b = inputStream.read()) != -1) { + bos.write(b); + } + return new BufferedResponse(bos.toByteArray()); + } finally { + close(); + } + } + + /** + * Save the result to a file. + * + * @param file the file + * @return this object + * @throws java.io.IOException on I/O error + */ + public HttpRequest saveContent(File file) throws IOException { + + try (Closer closer = Closer.create()) { + FileOutputStream fos = closer.register(new FileOutputStream(file)); + BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos)); + + saveContent(bos); + } + + return this; + } + + /** + * Save the result to an output stream. + * + * @param out the output stream + * @return this object + * @throws java.io.IOException on I/O error + */ + public HttpRequest saveContent(OutputStream out) throws IOException { + BufferedInputStream bis; + + try { + String field = conn.getHeaderField("Content-Length"); + if (field != null) { + long len = Long.parseLong(field); + // if (len >= 0) { // Let's just not deal with really big numbers + // contentLength = len; + // } + } + } catch (NumberFormatException ignored) { + } + + try { + bis = new BufferedInputStream(inputStream); + + byte[] data = new byte[READ_BUFFER_SIZE]; + int len; + while ((len = bis.read(data, 0, READ_BUFFER_SIZE)) >= 0) { + out.write(data, 0, len); + readBytes += len; + } + } finally { + close(); + } + + return this; + } + + /** + * Used with {@link #bodyForm(Form)}. + */ + public static final class Form { + public final List elements = new ArrayList<>(); + + private Form() { + } + + /** + * Create a new form. + * + * @return a new form + */ + public static Form create() { + return new Form(); + } + + /** + * Add a key/value to the form. + * + * @param key the key + * @param value the value + * @return this object + */ + public Form add(String key, String value) { + try { + elements.add(URLEncoder.encode(key, "UTF-8") + "=" + URLEncoder.encode(value, "UTF-8")); + return this; + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + boolean first = true; + for (String element : elements) { + if (first) { + first = false; + } else { + builder.append("&"); + } + builder.append(element); + } + return builder.toString(); + } + + } + + /** + * Used to buffer the response in memory. + */ + public static class BufferedResponse { + private final byte[] data; + + private BufferedResponse(byte[] data) { + this.data = data; + } + + /** + * Return the result as bytes. + * + * @return the data + */ + public byte[] asBytes() { + return data; + } + + /** + * Return the result as a string. + * + * @param encoding the encoding + * @return the string + * @throws java.io.IOException on I/O error + */ + public String asString(String encoding) throws IOException { + return new String(data, encoding); + } + + /** + * Save the result to a file. + * + * @param file the file + * @return this object + * @throws java.io.IOException on I/O error + */ + public BufferedResponse saveContent(File file) throws IOException { + + try (Closer closer = Closer.create()) { + file.getParentFile().mkdirs(); + FileOutputStream fos = closer.register(new FileOutputStream(file)); + BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos)); + + saveContent(bos); + } + + return this; + } + + /** + * Save the result to an output stream. + * + * @param out the output stream + * @return this object + * @throws java.io.IOException on I/O error + */ + public BufferedResponse saveContent(OutputStream out) throws IOException { + out.write(data); + + return this; + } + + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/sk89q/worldedit/util/paste/EngineHubPaster.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/sk89q/worldedit/util/paste/EngineHubPaster.java new file mode 100644 index 0000000..ca0f039 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/com/sk89q/worldedit/util/paste/EngineHubPaster.java @@ -0,0 +1,80 @@ +package org.abc.A.L.com.sk89q.worldedit.util.paste; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import java.io.IOException; +import java.net.URL; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.abc.A.L.com.sk89q.worldedit.util.net.HttpRequest; + +public class EngineHubPaster { + /* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + + private static final Pattern URL_PATTERN = Pattern.compile("https?://.+$"); + + private static final Gson GSON = new Gson(); + + public Callable paste(String content) { + return new PasteTask(content); + } + + private static final class PasteTask implements Callable { + private final String content; + + private PasteTask(String content) { + this.content = content; + } + + @Override + public URL call() throws IOException { + HttpRequest.Form form = HttpRequest.Form.create(); + form.add("content", content); + form.add("from", "enginehub"); + + URL url = HttpRequest.url("https://paste.enginehub.org/paste"); + String result = + HttpRequest.post(url) + .bodyForm(form) + .execute() + .expectResponseCode(200) + .returnContent() + .asString("UTF-8") + .trim(); + + Map object = + GSON.fromJson(result, new TypeToken>() { + }.getType()); + if (object != null) { + String urlString = String.valueOf(object.get("url")); + Matcher m = URL_PATTERN.matcher(urlString); + + if (m.matches()) { + return new URL(urlString); + } + } + throw new IOException("Failed to save paste; instead, got: " + result); + } + + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/de/Keyle/MyPet/api/util/Colorizer.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/de/Keyle/MyPet/api/util/Colorizer.java new file mode 100644 index 0000000..786c52d --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/de/Keyle/MyPet/api/util/Colorizer.java @@ -0,0 +1,56 @@ +/* + * This file is part of MyPet + * + * Copyright © 2011-2019 Keyle + * MyPet is licensed under the GNU Lesser General Public License. + * + * MyPet is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MyPet is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.abc.A.L.de.Keyle.MyPet.api.util; + +import java.util.HashMap; +import java.util.Map; +import org.bukkit.ChatColor; + +public class Colorizer { + + private static final Map colorCodes = new HashMap<>(); + + static { + for (ChatColor color : ChatColor.values()) { + colorCodes.put(color.name().replace("_", ""), String.valueOf(color.getChar())); + colorCodes.put(color.name(), String.valueOf(color.getChar())); + } + } + + public static String setColors(String text) { + for (String color : colorCodes.keySet()) { + text = text.replaceAll("(?i)<" + color + ">", ChatColor.COLOR_CHAR + colorCodes.get(color)); + } + text = text.replaceAll("(?i)<([0-9a-fk-or])>", ChatColor.COLOR_CHAR + "$1"); + text = ChatColor.translateAlternateColorCodes('&', text); + return text; + } + + public static String stripColors(String text) { + for (String color : colorCodes.keySet()) { + text = text.replaceAll("(?i)<" + color + ">", ""); + } + text = text.replaceAll("(?i)<[0-9a-fk-or]>", ""); + text = ChatColor.stripColor(text); + return text; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/de/Keyle/MyPet/api/util/LogFormat.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/de/Keyle/MyPet/api/util/LogFormat.java new file mode 100644 index 0000000..ea2ad4d --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/de/Keyle/MyPet/api/util/LogFormat.java @@ -0,0 +1,61 @@ +/* + * This file is part of MyPet + * + * Copyright © 2011-2019 Keyle + * MyPet is licensed under the GNU Lesser General Public License. + * + * MyPet is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MyPet is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.abc.A.L.de.Keyle.MyPet.api.util; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.logging.Formatter; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +public class LogFormat extends Formatter { + @Override + public String format(LogRecord record) { + String text = "[" + new SimpleDateFormat("HH:mm:ss").format(new Date(record.getMillis())); + Level level = record.getLevel(); + + if (level == Level.WARNING) { + text += " WARNING]"; + } else if (level == Level.SEVERE) { + text += " SEVERE]"; + } else { + text += " INFO]"; + } + + text += " " + record.getMessage(); + text += "\r\n"; + + Throwable thrown = record.getThrown(); + if (thrown != null) { + StringWriter stringWriter = new StringWriter(); + thrown.printStackTrace(new PrintWriter(stringWriter)); + text += stringWriter; + } + + text = text.replaceAll("(\\u001b\\[\\d{1,3}(?:;\\d+)*m|(?:\\u001b\\[m)*)", ""); + // text = Colorizer.stripColors(text); + + return text; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/de/Keyle/MyPet/api/util/ReflectionUtil.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/de/Keyle/MyPet/api/util/ReflectionUtil.java new file mode 100644 index 0000000..d2daafb --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/de/Keyle/MyPet/api/util/ReflectionUtil.java @@ -0,0 +1,120 @@ +/* + * This file is part of MyPet + * + * Copyright © 2011-2019 Keyle + * MyPet is licensed under the GNU Lesser General Public License. + * + * MyPet is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MyPet is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.abc.A.L.de.Keyle.MyPet.api.util; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import org.jetbrains.annotations.Nullable; + +public class ReflectionUtil { + + public static Class getClass(String name) { + try { + return Class.forName(name); + } catch (Throwable ignored) { + return Class.class; + } + } + + @Nullable + public static Method getMethod(Class clazz, String method, Class... parameterTypes) { + try { + Method m = clazz.getDeclaredMethod(method, parameterTypes); + m.setAccessible(true); + return m; + } catch (Throwable ignored) { + return null; + } + } + + @Nullable + public static Object getFieldValue(Class clazz, Object target, String field) { + try { + Field f = clazz.getDeclaredField(field); + f.setAccessible(true); + return f.get(target); + } catch (Throwable ignored) { + return null; + } + } + + @Nullable + public static Object getFieldValue(Field field, Object target) { + try { + return field.get(target); + } catch (Throwable ignored) { + } + return null; + } + + public static boolean setFieldValue(Field field, Object target, Object value) { + try { + field.set(target, value); + return true; + } catch (Throwable e) { + return false; + } + } + + public static boolean setFieldValue(String fieldName, Object target, Object value) { + try { + Field field = getField(target.getClass(), fieldName); + if (field != null) { + field.set(target, value); + return true; + } + } catch (Throwable ignored) { + } + return false; + } + + @Nullable + public static Field getField(Class clazz, String field) { + try { + Field f = clazz.getDeclaredField(field); + f.setAccessible(true); + return f; + } catch (Throwable ignored) { + return null; + } + } + + public static void setFinalStaticValue(Field field, Object newValue) + throws NoSuchFieldException, IllegalAccessException { + field.setAccessible(true); + + Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); + + field.set(null, newValue); + } + + public static boolean isTypeOf(Class clazz, Class superClass) { + if (!clazz.equals(superClass)) { + clazz = clazz.getSuperclass(); + return !clazz.equals(Object.class) && isTypeOf(clazz, superClass); + } + return true; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/me/lucko/spark/common/util/FormatUtil.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/me/lucko/spark/common/util/FormatUtil.java new file mode 100644 index 0000000..09cd38f --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/me/lucko/spark/common/util/FormatUtil.java @@ -0,0 +1,19 @@ +package org.abc.A.L.me.lucko.spark.common.util; + +public enum FormatUtil { + ; + + public static String percent(double value, double max) { + double percent = (value * 100d) / max; + return (int) percent + "%"; + } + + public static String formatBytes(long bytes) { + if (bytes == 0) { + return "0 bytes"; + } + String[] sizes = new String[]{"bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}; + int sizeIndex = (int) (Math.log(bytes) / Math.log(1024)); + return String.format("%.1f", bytes / Math.pow(1024, sizeIndex)) + " " + sizes[sizeIndex]; + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/me/lucko/spark/common/util/TypeDescriptors.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/me/lucko/spark/common/util/TypeDescriptors.java new file mode 100644 index 0000000..ce2a4d8 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/L/me/lucko/spark/common/util/TypeDescriptors.java @@ -0,0 +1,58 @@ +package org.abc.A.L.me.lucko.spark.common.util; + +public enum TypeDescriptors { + ; + + /** + * Returns the Java type corresponding to the given type descriptor. + * + * @param typeDescriptor a type descriptor. + * @return the Java type corresponding to the given type descriptor. + */ + public static String getJavaType(String typeDescriptor) { + return getJavaType(typeDescriptor.toCharArray(), 0); + } + + private static String getJavaType(char[] buf, int offset) { + int len; + switch (buf[offset]) { + case 'V': + return "void"; + case 'Z': + return "boolean"; + case 'C': + return "char"; + case 'B': + return "byte"; + case 'S': + return "short"; + case 'I': + return "int"; + case 'F': + return "float"; + case 'J': + return "long"; + case 'D': + return "double"; + case '[': // array + len = 1; + while (buf[offset + len] == '[') { + len++; + } + + StringBuilder sb = new StringBuilder(getJavaType(buf, offset + len)); + for (int i = len; i > 0; --i) { + sb.append("[]"); + } + return sb.toString(); + case 'L': // object + len = 1; + while (buf[offset + len] != ';') { + len++; + } + return new String(buf, offset + 1, len - 1); + default: + return new String(buf, offset, buf.length - offset); + } + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/Language.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/Language.java new file mode 100644 index 0000000..547d69d --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/Language.java @@ -0,0 +1,91 @@ +/* + * This file is a part of project QuickShop, the name is Language.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import org.abc.A.util.Copied; +import org.abc.A.util.Util; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class Language { + private final QuickShop plugin; + // private List languages = new ArrayList<>(); + + Language(QuickShop plugin) { + this.plugin = plugin; + } + + /** + * Save the target language's type file to the datafolder + * + * @param language Target language + * @param type Target type + * @param fileName The filename you want write to the plugin datafolder. + */ + public void saveFile(@NotNull String language, @NotNull String type, @NotNull String fileName) { + File targetFile = new File(plugin.getDataFolder(), fileName); + if (!targetFile.exists()) { + try { + targetFile.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + try { + InputStream is = getFile(language, type); + new Copied(targetFile).accept(is); + is.close(); + } catch (Exception err) { + err.printStackTrace(); + } + } + + // Write file under plugin folder + + /** + * Get target language's type file. + * + * @param language The target language + * @param type The file type for you want get. e.g. messages + * @return The target file's InputStream. + */ + public InputStream getFile(@Nullable String language, @Nullable String type) { + if (language == null) { + language = "en-US"; + Util.debugLog("Using the default language (EN) cause language is null."); + } + if (type == null || type.isEmpty()) { + throw new IllegalArgumentException("Type cannot be null or empty"); + } + InputStream inputStream = plugin.getResource("lang/" + language + "/" + type + ".json"); + if (inputStream == null) { + Util.debugLog("Using the default language because we can't get the InputStream."); + inputStream = plugin.getResource("lang/en-US/" + type + ".json"); + } + return inputStream; + // File name should call type-language.yml ---> config-zh.yml + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/BukkitPermsProvider.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/BukkitPermsProvider.java new file mode 100644 index 0000000..7d45079 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/BukkitPermsProvider.java @@ -0,0 +1,50 @@ +/* + * This file is a part of project QuickShop, the name is BukkitPermsProvider.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.M; + +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +public class BukkitPermsProvider implements PermissionProvider { + + @Override + public boolean hasPermission(@NotNull CommandSender sender, @NotNull String permission) { + return sender.hasPermission(permission); + } + + @Override + public @NotNull String getName() { + return "Bukkit"; + } + + /** + * Get the debug infos in provider + * + * @param sender CommandSender + * @param permission The permission want to check + * @return Debug Infos + */ + @Override + public @NotNull PermissionInfomationContainer getDebugInfo( + @NotNull CommandSender sender, @NotNull String permission) { + return new PermissionInfomationContainer(sender, permission, null, null); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionInfomationContainer.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionInfomationContainer.java new file mode 100644 index 0000000..5fd1577 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionInfomationContainer.java @@ -0,0 +1,53 @@ +/* + * This file is a part of project QuickShop, the name is PermissionInfomationContainer.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.M; + +import lombok.AllArgsConstructor; +import lombok.Data; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Data +@AllArgsConstructor +public class PermissionInfomationContainer { + @NotNull + private CommandSender sender; + + @NotNull + private String permission; + + @Nullable + private String groupName; + + @Nullable + private String otherInfos; + + /** + * Get sender is console + * + * @return yes or no + */ + public boolean isConsole() { + return sender instanceof Server; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionManager.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionManager.java new file mode 100644 index 0000000..b5c6bfe --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionManager.java @@ -0,0 +1,81 @@ +/* + * This file is a part of project QuickShop, the name is PermissionManager.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.M; + +import lombok.Getter; +import org.abc.A.util.Util; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.abc.A.QuickShop; + +@Getter +public class PermissionManager { + private QuickShop plugin; + + private PermissionProvider provider; + + /** + * The manager to call permission providers + * + * @param plugin Instance + */ + public PermissionManager(QuickShop plugin) { + this.plugin = plugin; + provider = new BukkitPermsProvider(); + plugin.getLogger().info("Selected permission provider: " + provider.getName()); + } + + /** + * Check the permission for sender + * + * @param sender The CommandSender you want check + * @param permission The permission node wait to check + * @return The result of check + */ + public boolean hasPermission(@NotNull CommandSender sender, @NotNull String permission) { + try { + boolean result = provider.hasPermission(sender, permission); + if (Util.isDevMode()) { + try { + PermissionInfomationContainer container = provider.getDebugInfo(sender, permission); + Util.debugLog("======="); + Util.debugLog("Result: " + result); + Util.debugLog("Sender: " + container.getSender().getName()); + Util.debugLog("Permission Node: " + container.getPermission()); + // Util.debugLog("Primary Group: " + container.getGroupName()); + // Util.debugLog("Other infos: " + container.getOtherInfos()); + } catch (Throwable th) { + th.printStackTrace(); + Util.debugLog("Exception throwed when getting debug messages."); + } + } + return result; + } catch (Throwable th) { + plugin.getSentryErrorReporter().ignoreThrow(); + th.printStackTrace(); + plugin + .getLogger() + .info( + "A error happend, if you believe this is QuickShop problem, please report to us on Issue Tracker or Discord."); + return false; + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionProvider.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionProvider.java new file mode 100644 index 0000000..6d642b7 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionProvider.java @@ -0,0 +1,54 @@ +/* + * This file is a part of project QuickShop, the name is PermissionProvider.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.M; + +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +public interface PermissionProvider { + /** + * Test the sender has special permission + * + * @param sender CommandSender + * @param permission The permission want to check + * @return hasPermission + */ + boolean hasPermission(@NotNull CommandSender sender, @NotNull String permission); + + /** + * Get permission provider name + * + * @return The name of permission provider + */ + @NotNull + String getName(); + + /** + * Get the debug infos in provider + * + * @param sender CommandSender + * @param permission The permission want to check + * @return Debug Infos + */ + @NotNull + PermissionInfomationContainer getDebugInfo( + @NotNull CommandSender sender, @NotNull String permission); + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionProviderType.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionProviderType.java new file mode 100644 index 0000000..451fb06 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/PermissionProviderType.java @@ -0,0 +1,44 @@ +/* + * This file is a part of project QuickShop, the name is PermissionProviderType.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.M; + +public enum PermissionProviderType { + // BUKKIT(0), VAULT(1), LUCKPERMS(2), PERMISSIONEX(3), GROUPMANAGER(4); + BUKKIT(0); + + final int id; + + PermissionProviderType(int id) { + this.id = id; + } + + public static PermissionProviderType fromID(int id) throws IllegalArgumentException { + for (PermissionProviderType child : PermissionProviderType.values()) { + if (child.toID() == id) { + return child; + } + } + throw new IllegalArgumentException("Type not exists"); + } + + public int toID() { + return this.id; + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/ProviderIsEmptyException.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/ProviderIsEmptyException.java new file mode 100644 index 0000000..11ff804 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/ProviderIsEmptyException.java @@ -0,0 +1,32 @@ +/* + * This file is a part of project QuickShop, the name is ProviderIsEmptyException.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.M; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +@AllArgsConstructor +public class ProviderIsEmptyException extends RuntimeException { + @Getter + @Setter + private String providerName; + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/VaultPermissionProvider.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/VaultPermissionProvider.java new file mode 100644 index 0000000..de56750 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/M/VaultPermissionProvider.java @@ -0,0 +1,84 @@ +/* + * This file is a part of project QuickShop, the name is VaultPermissionProvider.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.M; + +import net.milkbowl.vault.permission.Permission; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.jetbrains.annotations.NotNull; + +@Deprecated +public class VaultPermissionProvider implements PermissionProvider { + private Permission api; + + @Deprecated + public VaultPermissionProvider() { + RegisteredServiceProvider rsp = + Bukkit.getServer().getServicesManager().getRegistration(Permission.class); + if (rsp == null) { + throw new ProviderIsEmptyException(getName()); + } + api = rsp.getProvider(); + } + + /** + * Test the sender has special permission + * + * @param sender CommandSender + * @param permission The permission want to check + * @return hasPermission + */ + @Override + public boolean hasPermission(@NotNull CommandSender sender, @NotNull String permission) { + return api.has(sender, permission); + } + + /** + * Get permission provider name + * + * @return The name of permission provider + */ + @Override + public @NotNull String getName() { + return "Vault"; + } + + /** + * Get the debug infos in provider + * + * @param sender CommandSender + * @param permission The permission want to check + * @return Debug Infos + */ + @Override + public @NotNull PermissionInfomationContainer getDebugInfo( + @NotNull CommandSender sender, @NotNull String permission) { + if (sender instanceof Server) { + return new PermissionInfomationContainer(sender, permission, null, "User is Console"); + } + OfflinePlayer offlinePlayer = (OfflinePlayer) sender; + return new PermissionInfomationContainer( + sender, permission, api.getPrimaryGroup(null, offlinePlayer), null); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/Metrics.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/Metrics.java new file mode 100644 index 0000000..b9c7d4e --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/Metrics.java @@ -0,0 +1,760 @@ +package org.abc.A; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; +import java.io.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.concurrent.Callable; +import java.util.logging.Level; +import java.util.zip.GZIPOutputStream; +import javax.net.ssl.HttpsURLConnection; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.ServicePriority; + +/** + * bStats collects some data for plugin authors. + * + *

Check out https://bStats.org/ to learn more about bStats! + */ +@SuppressWarnings({"WeakerAccess", "unused"}) +public class Metrics { + + // The version of this bStats class + public static final int B_STATS_VERSION = 1; + + // The url to which the data is sent + private static final String URL = "https://bStats.org/submitData/bukkit"; + + // Should failed requests be logged? + private static boolean logFailedRequests; + + // Should the sent data be logged? + private static boolean logSentData; + + // Should the response text be logged? + private static boolean logResponseStatusText; + + // The uuid of the server + private static String serverUUID; + + static { + // You can use the property to disable the check in your test environment + if (System.getProperty("bstats.relocatecheck") == null + || !System.getProperty("bstats.relocatecheck").equals("false")) { + // Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" + // ... :D + final String defaultPackage = + new String( + new byte[]{ + 'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't' + }); + final String examplePackage = + new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'}); + // We want to make sure nobody just copy & pastes the example and use the wrong package names + if (Metrics.class.getPackage().getName().equals(defaultPackage) + || Metrics.class.getPackage().getName().equals(examplePackage)) { + throw new IllegalStateException("bStats Metrics class has not been relocated correctly!"); + } + } + } + + // The plugin + private final Plugin plugin; + + // The plugin id + private final int pluginId; + + // A list with all custom charts + private final List charts = new ArrayList<>(); + + // Is bStats enabled on this server? + private boolean enabled; + + private QuickShop quickShop; + + /** + * Class constructor. + * + * @param plugin The plugin which stats should be submitted. + * @param pluginId The id of the plugin. It can be found at What is my plugin id? + */ + public Metrics(Plugin plugin, int pluginId) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null!"); + } + this.plugin = plugin; + this.pluginId = pluginId; + + // Get the config file + File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats"); + File configFile = new File(bStatsFolder, "config.yml"); + YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); + + // Check if the config file exists + if (!config.isSet("serverUuid")) { + + // Add default values + config.addDefault("enabled", true); + // Every server gets it's unique random id. + config.addDefault("serverUuid", UUID.randomUUID().toString()); + // Should failed request be logged? + config.addDefault("logFailedRequests", false); + // Should the sent data be logged? + config.addDefault("logSentData", false); + // Should the response text be logged? + config.addDefault("logResponseStatusText", false); + + // Inform the server owners about bStats + config + .options() + .header( + "bStats collects some data for plugin authors like how many servers are using their plugins.\n" + + "To honor their work, you should not disable it.\n" + + "This has nearly no effect on the server performance!\n" + + "Check out https://bStats.org/ to learn more :)") + .copyDefaults(true); + try { + config.save(configFile); + } catch (IOException ignored) { + } + } + + // Load the data + enabled = config.getBoolean("enabled", true); + serverUUID = config.getString("serverUuid"); + logFailedRequests = config.getBoolean("logFailedRequests", false); + logSentData = config.getBoolean("logSentData", false); + logResponseStatusText = config.getBoolean("logResponseStatusText", false); + + if (enabled) { + boolean found = false; + // Search for all other bStats Metrics classes to see if we are the first one + for (Class service : Bukkit.getServicesManager().getKnownServices()) { + try { + service.getField("B_STATS_VERSION"); // Our identifier :) + found = true; // We aren't the first + break; + } catch (NoSuchFieldException ignored) { + } + } + // Register our service + Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal); + if (!found) { + // We are the first! + startSubmitting(); + } + } + } + + /** + * Starts the Scheduler which submits our data every 30 minutes. + */ + private void startSubmitting() { + final Timer timer = + new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags + timer.scheduleAtFixedRate( + new TimerTask() { + @Override + public void run() { + if (!plugin.isEnabled()) { // Plugin was disabled + timer.cancel(); + return; + } + // Nevertheless we want our code to run in the Bukkit main thread, so we have to use the + // Bukkit scheduler + // Don't be afraid! The connection to the bStats server is still async, only the stats + // collection is sync ;) + Bukkit.getScheduler().runTask(plugin, () -> submitData()); + } + }, + 1000 * 60 * 5, + 1000 * 60 * 30); + // Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough + // time to start + // WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted! + // WARNING: Just don't do it! + } + + /** + * Collects the data and sends it afterwards. + */ + private void submitData() { + final JsonObject data = getServerData(); + + JsonArray pluginData = new JsonArray(); + // Search for all other bStats Metrics classes to get their plugin data + for (Class service : Bukkit.getServicesManager().getKnownServices()) { + try { + service.getField("B_STATS_VERSION"); // Our identifier :) + + for (RegisteredServiceProvider provider : + Bukkit.getServicesManager().getRegistrations(service)) { + try { + Object plugin = + provider.getService().getMethod("getPluginData").invoke(provider.getProvider()); + if (plugin instanceof JsonObject) { + pluginData.add((JsonObject) plugin); + } else { // old bstats version compatibility + try { + Class jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject"); + if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) { + Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString"); + jsonStringGetter.setAccessible(true); + String jsonString = (String) jsonStringGetter.invoke(plugin); + JsonObject object = new JsonParser().parse(jsonString).getAsJsonObject(); + pluginData.add(object); + } + } catch (ClassNotFoundException e) { + // minecraft version 1.14+ + if (logFailedRequests) { + this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception", e); + } + } + } + } catch (NullPointerException + | NoSuchMethodException + | IllegalAccessException + | InvocationTargetException ignored) { + } + } + } catch (NoSuchFieldException ignored) { + } + } + + data.add("plugins", pluginData); + + // Create a new thread for the connection to the bStats server + new Thread( + () -> { + try { + // Send the data + sendData(plugin, data); + } catch (Exception e) { + // Something went wrong! :( + if (logFailedRequests) { + plugin + .getLogger() + .log( + Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e); + } + } + }) + .start(); + } + + /** + * Gets the server specific data. + * + * @return The server specific data. + */ + private JsonObject getServerData() { + // Minecraft specific data + int playerAmount; + try { + // Around MC 1.8 the return type was changed to a collection from an array, + // This fixes java.lang.NoSuchMethodError: + // org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection; + Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers"); + playerAmount = + onlinePlayersMethod.getReturnType().equals(Collection.class) + ? ((Collection) onlinePlayersMethod.invoke(Bukkit.getServer())).size() + : ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length; + } catch (Exception e) { + playerAmount = + Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed + } + int onlineMode = Bukkit.getOnlineMode() ? 1 : 0; + String bukkitVersion = Bukkit.getVersion(); + String bukkitName = Bukkit.getName(); + + // OS/Java specific data + String javaVersion = System.getProperty("java.version"); + String osName = System.getProperty("os.name"); + String osArch = System.getProperty("os.arch"); + String osVersion = System.getProperty("os.version"); + int coreCount = Runtime.getRuntime().availableProcessors(); + + JsonObject data = new JsonObject(); + + data.addProperty("serverUUID", serverUUID); + + data.addProperty("playerAmount", playerAmount); + data.addProperty("onlineMode", onlineMode); + data.addProperty("bukkitVersion", bukkitVersion); + data.addProperty("bukkitName", bukkitName); + + data.addProperty("javaVersion", javaVersion); + data.addProperty("osName", osName); + data.addProperty("osArch", osArch); + data.addProperty("osVersion", osVersion); + data.addProperty("coreCount", coreCount); + + return data; + } + + /** + * Sends the data to the bStats server. + * + * @param plugin Any plugin. It's just used to get a logger instance. + * @param data The data to send. + * @throws Exception If the request failed. + */ + private static void sendData(Plugin plugin, JsonObject data) throws Exception { + if (data == null) { + throw new IllegalArgumentException("Data cannot be null!"); + } + if (Bukkit.isPrimaryThread()) { + throw new IllegalAccessException("This method must not be called from the main thread!"); + } + if (logSentData) { + plugin.getLogger().info("Sending data to bStats: " + data); + } + HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection(); + + // Compress the data to save bandwidth + byte[] compressedData = compress(data.toString()); + + // Add headers + connection.setRequestMethod("POST"); + connection.addRequestProperty("Accept", "application/json"); + connection.addRequestProperty("Connection", "close"); + connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request + connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length)); + connection.setRequestProperty( + "Content-Type", "application/json"); // We send our data in JSON format + connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION); + + // Send data + connection.setDoOutput(true); + try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) { + outputStream.write(compressedData); + } + + StringBuilder builder = new StringBuilder(); + try (BufferedReader bufferedReader = + new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + String line; + while ((line = bufferedReader.readLine()) != null) { + builder.append(line); + } + } + + if (logResponseStatusText) { + plugin.getLogger().info("Sent data to bStats and received response: " + builder); + } + } + + /** + * Gzips the given String. + * + * @param str The string to gzip. + * @return The gzipped String. + * @throws IOException If the compression failed. + */ + private static byte[] compress(final String str) throws IOException { + if (str == null) { + return null; + } + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) { + gzip.write(str.getBytes(StandardCharsets.UTF_8)); + } + return outputStream.toByteArray(); + } + + /** + * Checks if bStats is enabled. + * + * @return Whether bStats is enabled or not. + */ + public boolean isEnabled() { + return enabled; + } + + /** + * Adds a custom chart. + * + * @param chart The chart to add. + */ + public void addCustomChart(CustomChart chart) { + if (chart == null) { + throw new IllegalArgumentException("Chart cannot be null!"); + } + charts.add(chart); + } + + /** + * Gets the plugin specific data. This method is called using Reflection. + * + * @return The plugin specific data. + */ + public JsonObject getPluginData() { + JsonObject data = new JsonObject(); + + String pluginName = "QuickShop-Reremake"; + String pluginVersion = plugin.getDescription().getVersion(); + + data.addProperty("pluginName", pluginName); // Append the name of the plugin + data.addProperty("id", pluginId); // Append the id of the plugin + data.addProperty("pluginVersion", pluginVersion); // Append the version of the plugin + JsonArray customCharts = new JsonArray(); + for (CustomChart customChart : charts) { + // Add the data of the custom charts + JsonObject chart = customChart.getRequestJsonObject(); + if (chart == null) { // If the chart is null, we skip it + continue; + } + customCharts.add(chart); + } + data.add("customCharts", customCharts); + + return data; + } + + /** + * Represents a custom chart. + */ + public abstract static class CustomChart { + + // The id of the chart + final String chartId; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + */ + CustomChart(String chartId) { + if (chartId == null || chartId.isEmpty()) { + throw new IllegalArgumentException("ChartId cannot be null or empty!"); + } + this.chartId = chartId; + } + + private JsonObject getRequestJsonObject() { + JsonObject chart = new JsonObject(); + chart.addProperty("chartId", chartId); + try { + JsonObject data = getChartData(); + if (data == null) { + // If the data is null we don't send the chart. + return null; + } + chart.add("data", data); + } catch (Throwable t) { + if (logFailedRequests) { + Bukkit.getLogger() + .log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t); + } + return null; + } + return chart; + } + + protected abstract JsonObject getChartData() throws Exception; + + } + + /** + * Represents a custom simple pie. + */ + public static class SimplePie extends CustomChart { + + private final Callable callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public SimplePie(String chartId, Callable callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + String value = callable.call(); + if (value == null || value.isEmpty()) { + // Null = skip the chart + return null; + } + data.addProperty("value", value); + return data; + } + + } + + /** + * Represents a custom advanced pie. + */ + public static class AdvancedPie extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public AdvancedPie(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + JsonObject values = new JsonObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() == 0) { + continue; // Skip this invalid + } + allSkipped = false; + values.addProperty(entry.getKey(), entry.getValue()); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.add("values", values); + return data; + } + + } + + /** + * Represents a custom drilldown pie. + */ + public static class DrilldownPie extends CustomChart { + + private final Callable>> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public DrilldownPie(String chartId, Callable>> callable) { + super(chartId); + this.callable = callable; + } + + @Override + public JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + JsonObject values = new JsonObject(); + Map> map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean reallyAllSkipped = true; + for (Map.Entry> entryValues : map.entrySet()) { + JsonObject value = new JsonObject(); + boolean allSkipped = true; + for (Map.Entry valueEntry : map.get(entryValues.getKey()).entrySet()) { + value.addProperty(valueEntry.getKey(), valueEntry.getValue()); + allSkipped = false; + } + if (!allSkipped) { + reallyAllSkipped = false; + values.add(entryValues.getKey(), value); + } + } + if (reallyAllSkipped) { + // Null = skip the chart + return null; + } + data.add("values", values); + return data; + } + + } + + /** + * Represents a custom single line chart. + */ + public static class SingleLineChart extends CustomChart { + + private final Callable callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public SingleLineChart(String chartId, Callable callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + int value = callable.call(); + if (value == 0) { + // Null = skip the chart + return null; + } + data.addProperty("value", value); + return data; + } + + } + + /** + * Represents a custom multi line chart. + */ + public static class MultiLineChart extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public MultiLineChart(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + JsonObject values = new JsonObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() == 0) { + continue; // Skip this invalid + } + allSkipped = false; + values.addProperty(entry.getKey(), entry.getValue()); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.add("values", values); + return data; + } + + } + + /** + * Represents a custom simple bar chart. + */ + public static class SimpleBarChart extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public SimpleBarChart(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + JsonObject values = new JsonObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + for (Map.Entry entry : map.entrySet()) { + JsonArray categoryValues = new JsonArray(); + categoryValues.add(new JsonPrimitive(entry.getValue())); + values.add(entry.getKey(), categoryValues); + } + data.add("values", values); + return data; + } + + } + + /** + * Represents a custom advanced bar chart. + */ + public static class AdvancedBarChart extends CustomChart { + + private final Callable> callable; + + /** + * Class constructor. + * + * @param chartId The id of the chart. + * @param callable The callable which is used to request the chart data. + */ + public AdvancedBarChart(String chartId, Callable> callable) { + super(chartId); + this.callable = callable; + } + + @Override + protected JsonObject getChartData() throws Exception { + JsonObject data = new JsonObject(); + JsonObject values = new JsonObject(); + Map map = callable.call(); + if (map == null || map.isEmpty()) { + // Null = skip the chart + return null; + } + boolean allSkipped = true; + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue().length == 0) { + continue; // Skip this invalid + } + allSkipped = false; + JsonArray categoryValues = new JsonArray(); + for (int categoryValue : entry.getValue()) { + categoryValues.add(new JsonPrimitive(categoryValue)); + } + values.add(entry.getKey(), categoryValues); + } + if (allSkipped) { + // Null = skip the chart + return null; + } + data.add("values", values); + return data; + } + + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ArmorStandDisplayItem.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ArmorStandDisplayItem.java new file mode 100644 index 0000000..c097311 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ArmorStandDisplayItem.java @@ -0,0 +1,331 @@ +/* + * This file is a part of project QuickShop, the name is ArmorStandDisplayItem.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import java.util.Objects; +import lombok.ToString; +import org.abc.A.util.Util; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.Directional; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.util.EulerAngle; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.G.ShopDisplayItemDespawnEvent; +import org.abc.A.G.ShopDisplayItemSpawnEvent; + +@ToString +public class ArmorStandDisplayItem extends DisplayItem { + + @Nullable + private volatile ArmorStand armorStand; + + + ArmorStandDisplayItem(@NotNull Shop shop) { + super(shop); + } + + private static boolean isTool(Material material) { + String nlc = material.name().toLowerCase(); + return nlc.contains("sword") || nlc.contains("shovel") || nlc.contains("axe"); + } + + @Override + public boolean checkDisplayIsMoved() { + if (this.armorStand == null) { + return false; + } + return !this.armorStand.getLocation().equals(getDisplayLocation()); + } + + public Location getCenter(Location loc) { + // This is always '+' instead of '-' even in negative pos + return new Location( + loc.getWorld(), loc.getBlockX() + .5, loc.getBlockY() + .5, loc.getBlockZ() + .5); + } + + @Override + public boolean checkDisplayNeedRegen() { + if (this.armorStand == null) { + return false; + } + return !this.armorStand.isValid() || this.armorStand.isDead(); + } + + @Override + public boolean checkIsShopEntity(@NotNull Entity entity) { + if (!(entity instanceof ArmorStand)) { + return false; + } + return DisplayItem.checkIsGuardItemStack(((ArmorStand) entity).getItemInHand()); + } + + @Override + public void fixDisplayMoved() { + Location location = this.getDisplayLocation(); + if (this.armorStand != null) { + if (location != null) { + this.armorStand.teleport(location); + } else { + fixDisplayMovedOld(); + } + } else { + fixDisplayMovedOld(); + } + } + + public void fixDisplayMovedOld() { + for (Entity entity : Objects.requireNonNull(this.shop.getLocation().getWorld()).getEntities()) { + if (!(entity instanceof ArmorStand)) { + continue; + } + ArmorStand eArmorStand = (ArmorStand) entity; + if (eArmorStand.getUniqueId().equals(Objects.requireNonNull(this.armorStand).getUniqueId())) { + Util.debugLog( + "Fixing moved ArmorStand displayItem " + + eArmorStand.getUniqueId() + + " at " + + eArmorStand.getLocation()); + eArmorStand.teleport(getDisplayLocation()); + return; + } + } + } + + @Override + public void fixDisplayNeedRegen() { + respawn(); + } + + @Override + public void remove() { + if (this.armorStand == null) { + Util.debugLog("Ignore the armorStand removing because the armorStand not spawned."); + return; + } + this.armorStand.remove(); + this.armorStand = null; + this.guardedIstack = null; + ShopDisplayItemDespawnEvent shopDisplayItemDespawnEvent = + new ShopDisplayItemDespawnEvent(this.shop, this.originalItemStack, DisplayType.ARMORSTAND); + Bukkit.getPluginManager().callEvent(shopDisplayItemDespawnEvent); + } + + @Override + public boolean removeDupe() { + if (this.armorStand == null) { + Util.debugLog("Warning: Trying to removeDupe for a null display shop."); + return false; + } + boolean removed = false; + for (Entity entity : armorStand.getNearbyEntities(1.5, 1.5, 1.5)) { + if (entity.getType() != EntityType.ARMOR_STAND) { + continue; + } + ArmorStand eArmorStand = (ArmorStand) entity; + + if (!eArmorStand.getUniqueId().equals(this.armorStand.getUniqueId())) { + if (DisplayItem.checkIsTargetShopDisplay(eArmorStand.getItemInHand(), this.shop)) { + Util.debugLog("Removing dupes ArmorEntity " + eArmorStand.getUniqueId() + " at " + eArmorStand.getLocation()); + entity.remove(); + removed = true; + } + } + } + return removed; + } + + @Override + public void respawn() { + remove(); + spawn(); + } + + @Override + public void safeGuard(@NotNull Entity entity) { + if (!(entity instanceof ArmorStand)) { + Util.debugLog( + "Failed to safeGuard " + entity.getLocation() + ", cause target not a ArmorStand"); + return; + } + ArmorStand armorStand = (ArmorStand) entity; + // Set item protect in the armorstand's hand + this.guardedIstack = DisplayItem.createGuardItemStack(this.originalItemStack, this.shop); + armorStand.setHelmet(guardedIstack); + try { + armorStand + .getPersistentDataContainer() + .set( + new NamespacedKey(plugin, "displayMark"), + DisplayItemPersistentDataType.INSTANCE, + DisplayItem.createShopProtectionFlag(this.originalItemStack, shop)); + } catch (Throwable ignored) { + } + } + + @Override + public void spawn() { + if (shop.getLocation().getWorld() == null) { + Util.debugLog("Canceled the displayItem spawning because the location in the world is null."); + return; + } + + if (originalItemStack == null) { + Util.debugLog("Canceled the displayItem spawning because the ItemStack is null."); + return; + } + + if (armorStand != null && armorStand.isValid() && !armorStand.isDead()) { + Util.debugLog( + "Warning: Spawning the armorStand for DisplayItem when there is already an existing armorStand may cause a duplicated armorStand!"); + StackTraceElement[] traces = Thread.currentThread().getStackTrace(); + for (StackTraceElement trace : traces) { + Util.debugLog( + trace.getClassName() + "#" + trace.getMethodName() + "#" + trace.getLineNumber()); + } + + ShopDisplayItemSpawnEvent shopDisplayItemSpawnEvent = + new ShopDisplayItemSpawnEvent(shop, originalItemStack, DisplayType.ARMORSTAND); + Bukkit.getPluginManager().callEvent(shopDisplayItemSpawnEvent); + if (shopDisplayItemSpawnEvent.isCancelled()) { + Util.debugLog( + "Canceled the displayItem from spawning because a plugin setCancelled the spawning event, usually it is a QuickShop Add on"); + return; + } + + Location location = getDisplayLocation(); + this.armorStand = + this.shop + .getLocation() + .getWorld() + .spawn( + location, + ArmorStand.class, + armorStand -> { + // Set basic armorstand datas. + armorStand.setGravity(false); + armorStand.setVisible(false); + armorStand.setMarker(true); + armorStand.setCollidable(false); + armorStand.setSmall(true); + armorStand.setArms(false); + armorStand.setBasePlate(false); + armorStand.setSilent(true); + armorStand.setAI(false); + armorStand.setCanPickupItems(false); + // Set pose (this is for hand while we use helmet) + // setPoseForArmorStand(); + }); + // Set safeGuard + Util.debugLog( + "Spawned armor stand @ " + + this.armorStand.getLocation() + + " with UUID " + + this.armorStand.getUniqueId()); + safeGuard(this.armorStand); // Helmet must be set after spawning + } + } + + @Override + public @Nullable Entity getDisplay() { + return this.armorStand; + } + + @Override + public Location getDisplayLocation() { + BlockFace containerBlockFace = BlockFace.NORTH; // Set default vaule + if (this.shop.getLocation().getBlock().getBlockData() instanceof Directional) { + containerBlockFace = + ((Directional) this.shop.getLocation().getBlock().getBlockData()) + .getFacing(); // Replace by container face. + } + // Fix specific block facing + Material type = this.shop.getLocation().getBlock().getType(); + if (type.name().contains("ANVIL") + || type.name().contains("FENCE") + || type.name().contains("WALL")) { + switch (containerBlockFace) { + case SOUTH: + containerBlockFace = BlockFace.WEST; + break; + case NORTH: + containerBlockFace = BlockFace.EAST; + case EAST: + containerBlockFace = BlockFace.NORTH; + case WEST: + containerBlockFace = BlockFace.SOUTH; + default: + break; + } + } + + Location asloc = getCenter(this.shop.getLocation()); + Util.debugLog("containerBlockFace " + containerBlockFace); + if (this.originalItemStack.getType().isBlock()) { + asloc.add(0, 0.5, 0); + } + switch (containerBlockFace) { + case SOUTH: + asloc.add(0, -0.5, 0); + asloc.setYaw(0); + Util.debugLog("Block face as SOUTH"); + break; + case WEST: + asloc.add(0, -0.5, 0); + asloc.setYaw(90); + Util.debugLog("Block face as WEST"); + break; + case EAST: + asloc.add(0, -0.5, 0); + asloc.setYaw(-90); + Util.debugLog("Block face as EAST"); + break; + case NORTH: + asloc.add(0, -0.5, 0); + asloc.setYaw(180); + Util.debugLog("Block face as NORTH"); + break; + default: + break; + } + return asloc; + } + + @Override + public synchronized boolean isSpawned() { + return this.armorStand != null && this.armorStand.isValid(); + } + + @Deprecated // no use, will be removed soon + private void setPoseForArmorStand() { + if (this.originalItemStack.getType().isBlock()) { + Objects.requireNonNull(armorStand).setRightArmPose(new EulerAngle(-0.2, 0, 0)); + } else { + Objects.requireNonNull(armorStand).setRightArmPose(new EulerAngle(-89.5, 0, 0)); + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ContainerShop.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ContainerShop.java new file mode 100644 index 0000000..76bcd60 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ContainerShop.java @@ -0,0 +1,1036 @@ +/* + * This file is a part of project QuickShop, the name is ContainerShop.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import com.lishid.openinv.OpenInv; +import java.util.*; +import java.util.Map.Entry; +import java.util.logging.Level; +import lombok.EqualsAndHashCode; +import org.abc.A.G.*; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.Sign; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.Damageable; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.QuickShop; + +/** + * ChestShop core + */ +@EqualsAndHashCode +public class ContainerShop implements Shop { + @NotNull + private final ItemStack item; + + @NotNull + private final Location location; + + @Nullable + private DisplayItem displayItem; + + @EqualsAndHashCode.Exclude + private volatile boolean isLoaded = false; + + @EqualsAndHashCode.Exclude + private volatile boolean isDeleted = false; + + @EqualsAndHashCode.Exclude + private volatile boolean createBackup = false; + + private ShopModerator moderator; + + private QuickShop plugin; + + private double price; + + private ShopType shopType; + + private boolean unlimited; + + private ContainerShop(@NotNull ContainerShop s) { + this.displayItem = s.displayItem; + this.shopType = s.shopType; + this.item = s.item; + this.location = s.location; + this.plugin = s.plugin; + this.unlimited = s.unlimited; + this.moderator = s.moderator; + this.price = s.price; + this.isLoaded = s.isLoaded; + } + + /** + * Adds a new shop. + * + * @param location The location of the chest block + * @param price The cost per item + * @param item The itemstack with the properties we want. This is .cloned, no need to worry about + * references + * @param moderator The modertators + * @param type The shop type + * @param unlimited The unlimited + */ + public ContainerShop( + @NotNull Location location, + double price, + @NotNull ItemStack item, + @NotNull ShopModerator moderator, + boolean unlimited, + @NotNull ShopType type) { + this.location = location; + this.price = price; + this.moderator = moderator; + this.item = new ItemStack(item); + this.plugin = QuickShop.instance; + this.item.setAmount(1); + this.shopType = type; + this.unlimited = unlimited; + + if (plugin.isDisplay()) { + switch (DisplayItem.getNowUsing()) { + case UNKNOWN: + Util.debugLog( + "Failed to create a ContainerShop displayItem, the type is unknown, fallback to RealDisplayItem"); + this.displayItem = new RealDisplayItem(this); + break; + case REALITEM: + this.displayItem = new RealDisplayItem(this); + break; + case ARMORSTAND: + this.displayItem = new ArmorStandDisplayItem(this); + break; + case VIRTUALITEM: + try { + this.displayItem = new VirtualDisplayItem(this); + } catch (Throwable e) { + Util.debugLog(e.getMessage()); + Arrays.stream(e.getStackTrace()).forEach(ex -> Util.debugLog(ex.getClassName() + "#" + ex.getMethodName() + "#" + ex.getLineNumber())); + plugin.getConfig().set("shop.display-type", 0); + plugin.saveConfig(); + this.displayItem = new RealDisplayItem(this); + //do not throw + plugin.getLogger().log(Level.SEVERE, "Failed to initialize VirtualDisplayItem, fallback to RealDisplayItem, are you using the latest version of ProtocolLib?", e); + } + break; + default: + Util.debugLog( + "Warning: Failed to create a ContainerShop displayItem, the type we didn't know, fallback to RealDisplayItem"); + this.displayItem = new RealDisplayItem(this); + break; + } + } else { + Util.debugLog("The display was disabled."); + } + } + + /** + * Add an item to shops chest. + * + * @param item The itemstack. The amount does not matter, just everything else + * @param amount The amount to add to the shop. + */ + @Override + public void add(@NotNull ItemStack item, int amount) { + if (this.unlimited) { + return; + } + Inventory inv = this.getInventory(); + int remains = amount; + while (remains > 0) { + int stackSize = Math.min(remains, item.getMaxStackSize()); + item.setAmount(stackSize); + Objects.requireNonNull(inv).addItem(item); + remains -= stackSize; + } + this.setSignText(); + } + + @Override + public boolean addStaff(@NotNull UUID player) { + boolean result = this.moderator.addStaff(player); + update(); + if (result) { + Bukkit.getPluginManager().callEvent(new ShopModeratorChangedEvent(this, this.moderator)); + } + return result; + } + + /** + * Buys amount of item from Player p. Does NOT check our inventory, or balances + * + * @param p The player to buy from + * @param amount The amount to buy + */ + @Override + public void buy(@NotNull Player p, int amount) { + int amount1 = amount; + if (amount1 < 0) { + this.sell(p, -amount1); + } + ItemStack[] contents = p.getInventory().getContents(); + if (this.isUnlimited()) { + for (int i = 0; amount1 > 0 && i < contents.length; i++) { + ItemStack stack = contents[i]; + if (stack == null || stack.getType() == Material.AIR) { + continue; // No item + } + if (matches(stack)) { + int stackSize = Math.min(amount1, stack.getAmount()); + stack.setAmount(stack.getAmount() - stackSize); + amount1 -= stackSize; + } + } + // Send the players new inventory to them + p.getInventory().setContents(contents); + this.setSignText(); + // This should not happen. + if (amount1 > 0) { + plugin + .getLogger() + .log( + Level.WARNING, + "Could not take all items from a players inventory on purchase! " + + p.getName() + + ", missing: " + + amount1 + + ", item: " + + Util.getItemStackName(this.getItem()) + + "!"); + } + } else { + Inventory chestInv = this.getInventory(); + for (int i = 0; amount1 > 0 && i < contents.length; i++) { + ItemStack item = contents[i]; + if (item != null && this.matches(item)) { + // Copy it, we don't want to interfere + item = new ItemStack(item); + // Amount = total, item.getAmount() = how many items in the + // stack + int stackSize = Math.min(amount1, item.getAmount()); + // If Amount is item.getAmount(), then this sets the amount + // to 0 + // Else it sets it to the remainder + contents[i].setAmount(contents[i].getAmount() - stackSize); + // We can modify this, it is a copy. + item.setAmount(stackSize); + // Add the items to the players inventory + Objects.requireNonNull(chestInv).addItem(item); + amount1 -= stackSize; + } + } + // Now update the players inventory. + p.getInventory().setContents(contents); + this.setSignText(); + } + } + + @Override + public void checkDisplay() { + if (!plugin.isDisplay() || !this.isLoaded) { // FIXME: Reinit scheduler on reloading config + return; + } + + if (this.displayItem == null) { + Util.debugLog("Warning: DisplayItem is null, this shouldn't happend..."); + StackTraceElement traceElements = Thread.currentThread().getStackTrace()[2]; + Util.debugLog( + "Call from: " + + traceElements.getClassName() + + "#" + + traceElements.getMethodName() + + "%" + + traceElements.getLineNumber()); + return; + } + + if (!this.displayItem.isSpawned()) { + /* Not spawned yet. */ + Util.debugLog("Target item not spawned, spawning..."); + this.displayItem.spawn(); + } else { + /* If not spawned, we didn't need check these, only check them when we need. */ + if (this.displayItem.checkDisplayNeedRegen()) { + this.displayItem.fixDisplayNeedRegen(); + } else { + /* If display was regened, we didn't need check it moved, performance! */ + if (this.displayItem.checkDisplayIsMoved()) { + this.displayItem.fixDisplayMoved(); + } + } + } + + /* Dupe is always need check, if enabled display */ + this.displayItem.removeDupe(); + // plugin.getDisplayDupeRemoverWatcher().add(this.displayItem); + } + + @Override + public void clearStaffs() { + this.moderator.clearStaffs(); + Bukkit.getPluginManager().callEvent(new ShopModeratorChangedEvent(this, this.moderator)); + update(); + } + + @Override + public boolean delStaff(@NotNull UUID player) { + boolean result = this.moderator.delStaff(player); + update(); + if (result) { + Bukkit.getPluginManager().callEvent(new ShopModeratorChangedEvent(this, this.moderator)); + } + return result; + } + + /** + * Deletes the shop from the list of shops and queues it for database + */ + @Override + public void delete() { + delete(false); + } + + /** + * Deletes the shop from the list of shops and queues it for database deletion + * + * @param memoryOnly whether to delete from database + */ + @Override + public void delete(boolean memoryOnly) { + ShopDeleteEvent shopDeleteEvent = new ShopDeleteEvent(this, memoryOnly); + if (Util.fireCancellableEvent(shopDeleteEvent)) { + Util.debugLog("Shop deletion was canceled because a plugin canceled it."); + return; + } + isDeleted = true; + // Unload the shop + if (isLoaded) { + this.onUnload(); + } + // Delete the signs around it + for (Sign s : this.getSigns()) { + s.getBlock().setType(Material.AIR); + } + // Delete it from the database + // Refund if necessary + if (plugin.getConfig().getBoolean("shop.refund")) { + plugin.getEconomy().deposit(this.getOwner(), plugin.getConfig().getDouble("shop.cost")); + } + if (memoryOnly) { + // Delete it from memory + plugin.getShopManager().removeShop(this); + } else { + plugin.getShopManager().removeShop(this); + plugin.getDatabaseHelper().removeShop(this); + } + } + + @Override + public boolean isAttached(@NotNull Block b) { + return this.getLocation().getBlock().equals(Util.getAttached(b)); + } + + /** + * Returns true if the ItemStack matches what this shop is selling/buying + * + * @param item The ItemStack + * @return True if the ItemStack is the same (Excludes amounts) + */ + @Override + public boolean matches(@Nullable ItemStack item) { + return plugin.getItemMatcher().matches(this.item, item); + } + + @Override + public void onClick() { + ShopClickEvent event = new ShopClickEvent(this); + if (Util.fireCancellableEvent(event)) { + Util.debugLog("Ignore shop click, because some plugin cancel it."); + return; + } + this.setSignText(); + this.checkDisplay(); + } + + /** + * Load ContainerShop. + */ + @Override + public void onLoad() { + if (this.isLoaded) { + Util.debugLog("Dupe load request, canceled."); + return; + } + ShopLoadEvent shopLoadEvent = new ShopLoadEvent(this); + if (Util.fireCancellableEvent(shopLoadEvent)) { + return; + } + this.isLoaded = true; + Objects.requireNonNull(plugin.getShopManager().getLoadedShops()).add(this); + plugin.getShopContainerWatcher().scheduleCheck(this); + // check price restriction + Entry priceRestriction = Util.getPriceRestriction(this.getMaterial()); + if (priceRestriction != null) { + if (price < priceRestriction.getKey()) { + price = priceRestriction.getKey(); + this.update(); + } else if (price > priceRestriction.getValue()) { + price = priceRestriction.getValue(); + this.update(); + } + } + this.checkDisplay(); + } + + /** + * @return The ItemStack type of this shop + */ + public @NotNull Material getMaterial() { + return this.item.getType(); + } + + /** + * Unload ContainerShop. + */ + @Override + public void onUnload() { + if (!this.isLoaded) { + Util.debugLog("Dupe unload request, canceled."); + return; + } + if (this.getDisplayItem() != null) { + this.getDisplayItem().remove(); + } + update(); + this.isLoaded = false; + plugin.getShopManager().getLoadedShops().remove(this); + ShopUnloadEvent shopUnloadEvent = new ShopUnloadEvent(this); + Bukkit.getPluginManager().callEvent(shopUnloadEvent); + } + + @Override + public @NotNull String ownerName() { + if (this.isUnlimited()) { + return MsgUtil.getMessageOfflinePlayer( + "admin-shop", Bukkit.getOfflinePlayer(this.getOwner())); + } + String name = Bukkit.getOfflinePlayer(this.getOwner()).getName(); + if (name == null || name.isEmpty()) { + return MsgUtil.getMessageOfflinePlayer( + "unknown-owner", Bukkit.getOfflinePlayer(this.getOwner())); + } + return name; + } + + /** + * Removes an item from the shop. + * + * @param item The itemstack. The amount does not matter, just everything else + * @param amount The amount to remove from the shop. + */ + @Override + public void remove(@NotNull ItemStack item, int amount) { + if (this.unlimited) { + return; + } + Inventory inv = this.getInventory(); + int remains = amount; + while (remains > 0) { + int stackSize = Math.min(remains, item.getMaxStackSize()); + item.setAmount(stackSize); + Objects.requireNonNull(inv).removeItem(item); + remains -= stackSize; + } + this.setSignText(); + } + + /** + * Sells amount of item to Player p. Does NOT check our inventory, or balances + * + * @param p The player to sell to + * @param amount The amount to sell + */ + @Override + public void sell(@NotNull Player p, int amount) { + if (amount < 0) { + this.buy(p, -amount); + } + // Items to drop on floor + ArrayList floor = new ArrayList<>(5); + Inventory pInv = p.getInventory(); + if (this.isUnlimited()) { + ItemStack item = new ItemStack(this.item); + while (amount > 0) { + int stackSize = Math.min(amount, this.item.getMaxStackSize()); + item.setAmount(stackSize); + pInv.addItem(item); + amount -= stackSize; + } + } else { + ItemStack[] chestContents = Objects.requireNonNull(this.getInventory()).getContents(); + for (int i = 0; amount > 0 && i < chestContents.length; i++) { + // Can't clone it here, it could be null + ItemStack item = chestContents[i]; + if (item != null && item.getType() != Material.AIR && this.matches(item)) { + // Copy it, we don't want to interfere + item = new ItemStack(item); + // Amount = total, item.getAmount() = how many items in the + // stack + int stackSize = Math.min(amount, item.getAmount()); + // If Amount is item.getAmount(), then this sets the amount + // to 0 + // Else it sets it to the remainder + chestContents[i].setAmount(chestContents[i].getAmount() - stackSize); + // We can modify this, it is a copy. + item.setAmount(stackSize); + // Add the items to the players inventory + floor.addAll(pInv.addItem(item).values()); + amount -= stackSize; + } + } + // We now have to update the chests inventory manually. + this.getInventory().setContents(chestContents); + this.setSignText(); + } + for (ItemStack stack : floor) { + p.getWorld().dropItem(p.getLocation(), stack); + } + } + + /** + * Updates signs attached to the shop + */ + @Override + public void setSignText() { + if (!Util.isLoaded(this.location)) { + return; + } + String[] lines = new String[4]; + OfflinePlayer player = Bukkit.getOfflinePlayer(this.getOwner()); + lines[0] = MsgUtil.getMessageOfflinePlayer("signs.header", player, this.ownerName()); + if (this.isSelling()) { + if (this.getRemainingStock() == -1) { + lines[1] = + MsgUtil.getMessageOfflinePlayer( + "signs.selling", + player, + "" + MsgUtil.getMessageOfflinePlayer("signs.unlimited", player)); + } else { + lines[1] = + MsgUtil.getMessageOfflinePlayer("signs.selling", player, "" + this.getRemainingStock()); + } + + } else if (this.isBuying()) { + if (this.getRemainingSpace() == -1) { + lines[1] = + MsgUtil.getMessageOfflinePlayer( + "signs.buying", + player, + "" + MsgUtil.getMessageOfflinePlayer("signs.unlimited", player)); + + } else { + lines[1] = + MsgUtil.getMessageOfflinePlayer("signs.buying", player, "" + this.getRemainingSpace()); + } + } + lines[2] = + MsgUtil.getMessageOfflinePlayer( + "signs.item", player, Util.getItemStackName(this.getItem())); + lines[3] = MsgUtil.getMessageOfflinePlayer("signs.price", player, Util.format(this.getPrice())); + this.setSignText(lines); + } + + /** + * Upates the shop into the database. + */ + @Override + public void update() { + ShopUpdateEvent shopUpdateEvent = new ShopUpdateEvent(this); + if (Util.fireCancellableEvent(shopUpdateEvent)) { + Util.debugLog("The Shop update action was canceled by a plugin."); + return; + } + + int x = this.getLocation().getBlockX(); + int y = this.getLocation().getBlockY(); + int z = this.getLocation().getBlockZ(); + String world = Objects.requireNonNull(this.getLocation().getWorld()).getName(); + int unlimited = this.isUnlimited() ? 1 : 0; + try { + plugin + .getDatabaseHelper() + .updateShop( + ShopModerator.serialize(this.moderator.clone()), + this.getItem(), + unlimited, + shopType.toID(), + this.getPrice(), + x, + y, + z, + world); + } catch (Exception e) { + e.printStackTrace(); + plugin + .getLogger() + .log( + Level.WARNING, + "Could not update a shop in the database! Changes will revert after a reboot!"); + } + } + + /** + * @return The durability of the item + */ + @Override + public short getDurability() { + return (short) ((Damageable) this.item.getItemMeta()).getDamage(); + } + + /** + * @return Returns a dummy itemstack of the item this shop is selling. + */ + @Override + public @NotNull ItemStack getItem() { + return item; + } + + /** + * Changes all lines of text on a sign near the shop + * + * @param lines The array of lines to change. Index is line number. + */ + @Override + public void setSignText(@NotNull String[] lines) { + for (Sign sign : this.getSigns()) { + if (Arrays.equals(sign.getLines(), lines)) { + Util.debugLog("Skipped new sign text setup: Same content"); + continue; + } + for (int i = 0; i < lines.length; i++) { + sign.setLine(i, lines[i]); + } + sign.update(true); + } + } + + /** + * @return The location of the shops chest + */ + @Override + public @NotNull Location getLocation() { + return this.location; + } + + @Override + public @NotNull ShopModerator getModerator() { + return this.moderator; + } + + @Override + public void setModerator(ShopModerator shopModerator) { + this.moderator = shopModerator; + update(); + Bukkit.getPluginManager().callEvent(new ShopModeratorChangedEvent(this, this.moderator)); + } + + /** + * @return The name of the player who owns the shop. + */ + @Override + public @NotNull UUID getOwner() { + return this.moderator.getOwner(); + } + + /** + * Changes the owner of this shop to the given player. + * + * @param owner the new owner + */ + @Override + public void setOwner(@NotNull UUID owner) { + this.moderator.setOwner(owner); + Bukkit.getPluginManager().callEvent(new ShopModeratorChangedEvent(this, this.moderator)); + this.setSignText(); + update(); + } + + /** + * @return The price per item this shop is selling + */ + @Override + public double getPrice() { + return this.price; + } + + /** + * Sets the price of the shop. + * + * @param price The new price of the shop. + */ + @Override + public void setPrice(double price) { + ShopPriceChangeEvent event = new ShopPriceChangeEvent(this, this.price, price); + if (Util.fireCancellableEvent(event)) { + Util.debugLog("A plugin cancelled the price change event."); + return; + } + this.price = price; + setSignText(); + update(); + } + + /** + * Returns the number of free spots in the chest for the particular item. + * + * @return remaining space + */ + @Override + public int getRemainingSpace() { + if (this.unlimited) { + return -1; + } + return Util.countSpace(this.getInventory(), this.getItem()); + } + + /** + * Returns the number of items this shop has in stock. + * + * @return The number of items available for purchase. + */ + @Override + public int getRemainingStock() { + if (this.unlimited) { + return -1; + } + return Util.countItems(this.getInventory(), this.getItem()); + } + + @Override + public @NotNull ShopType getShopType() { + return this.shopType; + } + + /** + * Changes a shop type to Buying or Selling. Also updates the signs nearby. + * + * @param shopType The new type (ShopType.BUYING or ShopType.SELLING) + */ + @Override + public void setShopType(@NotNull ShopType shopType) { + this.shopType = shopType; + this.setSignText(); + update(); + } + + /** + * Returns a list of signs that are attached to this shop (QuickShop and blank signs only) + * + * @return a list of signs that are attached to this shop (QuickShop and blank signs only) + */ + @Override + public @NotNull List getSigns() { + List signs = new ArrayList<>(1); + if (this.getLocation().getWorld() == null) { + return signs; + } + Block[] blocks = new Block[4]; + blocks[0] = location.getBlock().getRelative(BlockFace.EAST); + blocks[1] = location.getBlock().getRelative(BlockFace.NORTH); + blocks[2] = location.getBlock().getRelative(BlockFace.SOUTH); + blocks[3] = location.getBlock().getRelative(BlockFace.WEST); + OfflinePlayer player = Bukkit.getOfflinePlayer(this.getOwner()); + final String signHeader = + MsgUtil.getMessageOfflinePlayer("sign.header", player, this.ownerName()); + + for (Block b : blocks) { + if (b == null) { + plugin.getLogger().warning("Null signs in the queue, skipping"); + continue; + } + + if (!(b.getState() instanceof Sign)) { + continue; + } + if (!isAttached(b)) { + continue; + } + org.bukkit.block.Sign sign = (org.bukkit.block.Sign) b.getState(); + String[] lines = sign.getLines(); + for (int i = 0; i < lines.length; i++) { + if (i == 0) { + if (lines[i].contains(signHeader)) { + signs.add(sign); + break; + } + } else { + if (Arrays.stream(lines).anyMatch((str) -> !str.isEmpty())) { + break; + } + } + } + signs.add(sign); + } + // if (currentLine.contains(signHeader) || currentLine.isEmpty()) { + // signs.add(sign); + // } else { + // boolean text = false; + // for (String s : sign.getLines()) { + // if (!s.isEmpty()) { + // text = true; + // break; + // } + // } + // if (!text) { + // signs.add(sign); + // } + // } + // } + return signs; + } + + /** + * @return The list of players who can manage the shop. + */ + @NotNull + @Override + public ArrayList getStaffs() { + return this.moderator.getStaffs(); + } + + @Override + public boolean isBuying() { + return this.shopType == ShopType.BUYING; + } + + @Override + public boolean isLoaded() { + return this.isLoaded; + } + + @Override + public boolean isSelling() { + return this.shopType == ShopType.SELLING; + } + + @Override + public boolean isUnlimited() { + return this.unlimited; + } + + @Override + public void setUnlimited(boolean unlimited) { + this.unlimited = unlimited; + this.setSignText(); + update(); + } + + /** + * Check shop is or not still Valid. + * + * @return isValid + */ + @Override + public boolean isValid() { + this.checkDisplay(); + return Util.canBeShop(this.getLocation().getBlock()); + } + + @Override + public boolean isDeleted() { + return isDeleted; + } + + @Override + public @Nullable DisplayItem getDisplay() { + return this.displayItem; + } + + /** + * Returns a clone of this shop. References to the same display item, itemstack, location and + * owner as this shop does. Do not modify them or you will modify this shop. + * + *

**NOT A DEEP CLONE** + */ + @Override + public @NotNull ContainerShop clone() { + return new ContainerShop(this); + } + + @Override + public String toString() { + StringBuilder sb = + new StringBuilder( + "Shop " + + (location.getWorld() == null ? "unloaded world" : location.getWorld().getName()) + + "(" + + location.getBlockX() + + ", " + + location.getBlockY() + + ", " + + location.getBlockZ() + + ")"); + sb.append(" Owner: ").append(this.ownerName()).append(" - ").append(getOwner()); + if (isUnlimited()) { + sb.append(" Unlimited: true"); + } + sb.append(" Price: ").append(getPrice()); + sb.append(" Item: ").append(getItem()); + return sb.toString(); + } + + /** + * Returns the display item associated with this shop. + * + * @return The display item associated with this shop. + */ + @Nullable + public DisplayItem getDisplayItem() { + return this.displayItem; + } + + /** + * @return The enchantments the shop has on its items. + */ + public @NotNull Map getEnchants() { + return Objects.requireNonNull(this.item.getItemMeta()).getEnchants(); + } + + /** + * @return The chest this shop is based on. + */ + + public @Nullable Inventory getInventory() { + try { + if (location.getBlock().getState().getType() == Material.ENDER_CHEST + && plugin.getOpenInvPlugin() != null) { + OpenInv openInv = ((OpenInv) plugin.getOpenInvPlugin()); + return openInv + .getSpecialEnderChest( + Objects.requireNonNull( + openInv.loadPlayer(Bukkit.getOfflinePlayer(this.moderator.getOwner()))), + Bukkit.getOfflinePlayer((this.moderator.getOwner())).isOnline()) + .getBukkitInventory(); + } + } catch (Exception e) { + Util.debugLog(e.getMessage()); + return null; + } + InventoryHolder container; + try { + container = (InventoryHolder) this.location.getBlock().getState(); + return container.getInventory(); + } catch (Exception e) { + if (!createBackup) { + createBackup = Util.backupDatabase(); + if (createBackup) { + this.delete(); + Util.debugLog("Inventory doesn't exist anymore: " + this + " shop was removed."); + } + } else { + this.delete(); + Util.debugLog("Inventory doesn't exist anymore: " + this + " shop was removed."); + } + return null; + } + } + + /** + * Returns true if this shop is a double chest, and the other half is selling/buying the same as + * this is buying/selling. + * + * @return true if this shop is a double chest, and the other half is selling/buying the same as + * this is buying/selling. + */ + public boolean isDoubleShop() { + ContainerShop nextTo = this.getAttachedShop(); + if (nextTo == null) { + return false; + } + if (nextTo.matches(this.getItem())) { + // They're both trading the same item + // They're both buying or both selling => Not a double shop, + // just two shops. + // One is buying, one is selling. + return this.getShopType() != nextTo.getShopType(); + } else { + return false; + } + } + + /** + * Returns the shop that shares it's inventory with this one. + * + * @return the shop that shares it's inventory with this one. Will return null if this shop is not + * attached to another. + */ + public @Nullable ContainerShop getAttachedShop() { + Block c = Util.getSecondHalf(this.getLocation().getBlock()); + if (c == null) { + return null; + } + Shop shop = plugin.getShopManager().getShop(c.getLocation()); + return shop == null ? null : (ContainerShop) shop; + } + + /** + * Different with isDoubleShop, this method only check the shop is created on the double chest. + * + * @return true if create on double chest. + */ + public boolean isDoubleChestShop() { + return Util.isDoubleChest(this.getLocation().getBlock()); + } + + /** + * Check the container still there and we can keep use it. + */ + public void checkContainer() { + if (!this.isLoaded) { + return; + } + if (!Util.isLoaded(this.getLocation())) { + return; + } + if (!Util.canBeShop(this.getLocation().getBlock())) { + Util.debugLog("Shop at " + this.getLocation() + "@" + this.getLocation().getBlock() + " container was missing, remove..."); + this.onUnload(); + if (!createBackup) { + this.createBackup = Util.backupDatabase(); + } + if (createBackup) { + this.delete(); + } + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/DisplayItem.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/DisplayItem.java new file mode 100644 index 0000000..8a23918 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/DisplayItem.java @@ -0,0 +1,307 @@ +/* + * This file is a part of project QuickShop, the name is DisplayItem.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import java.util.ArrayList; + +import org.abc.A.util.Util; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.QuickShop; + +/** + * @author Netherfoam A display item, that spawns a block above the chest and cannot be interacted + * with. + */ +public abstract class DisplayItem { + + protected static final QuickShop plugin = QuickShop.instance; + + private static final Gson gson = new Gson(); + + protected final ItemStack originalItemStack; + + protected final Shop shop; + + @Nullable + protected ItemStack guardedIstack; + + private boolean pendingRemoval; + + protected DisplayItem(Shop shop) { + this.shop = shop; + this.originalItemStack = new ItemStack(shop.getItem()); + this.originalItemStack.setAmount(1); + } + + + /** + * Check the itemStack is contains protect flag. + * + * @param itemStack Target ItemStack + * @return Contains protect flag. + */ + public static boolean checkIsGuardItemStack(@Nullable ItemStack itemStack) { + + if (!plugin.isDisplay()) { + return false; + } + if (getNowUsing() == DisplayType.VIRTUALITEM) { + return false; + } + + if (itemStack == null) { + return false; + } + // itemStack = itemStack.clone(); + // itemStack.setAmount(1); + if (!itemStack.hasItemMeta()) { + return false; + } + ItemMeta iMeta = itemStack.getItemMeta(); + if (!iMeta.hasLore()) { + return false; + } + String defaultMark = ShopProtectionFlag.getDefaultMark(); + //noinspection ConstantConditions + for (String lore : iMeta.getLore()) { + try { + if (!lore.startsWith("{")) { + continue; + } + ShopProtectionFlag shopProtectionFlag = gson.fromJson(lore, ShopProtectionFlag.class); + if (shopProtectionFlag == null) { + continue; + } + if (defaultMark.equals(shopProtectionFlag.getMark())) { + return true; + } + if (shopProtectionFlag.getShopLocation() != null) { + return true; + } + if (shopProtectionFlag.getItemStackString() != null) { + return true; + } + } catch (JsonSyntaxException e) { + // Ignore + } + } + + return false; + } + + /** + * Get plugin now is using which one DisplayType + * + * @return Using displayType. + */ + public static DisplayType getNowUsing() { + return DisplayType.fromID(QuickShop.instance.getConfig().getInt("shop.display-type")); + } + + /** + * Check the itemStack is target shop's display + * + * @param itemStack Target ItemStack + * @param shop Target shop + * @return Is target shop's display + */ + public static boolean checkIsTargetShopDisplay(@NotNull ItemStack itemStack, @NotNull Shop shop) { + if (!plugin.isDisplay()) { + return false; + } + if (getNowUsing() == DisplayType.VIRTUALITEM) { + return false; + } + + if (!itemStack.hasItemMeta()) { + return false; + } + ItemMeta iMeta = itemStack.getItemMeta(); + if (!iMeta.hasLore()) { + return false; + } + String defaultMark = ShopProtectionFlag.getDefaultMark(); + String shopLocation = shop.getLocation().toString(); + //noinspection ConstantConditions + for (String lore : iMeta.getLore()) { + try { + if (!lore.startsWith("{")) { + continue; + } + ShopProtectionFlag shopProtectionFlag = gson.fromJson(lore, ShopProtectionFlag.class); + if (shopProtectionFlag == null) { + continue; + } + if (!shopProtectionFlag.getMark().equals(defaultMark)) { + continue; + } + if (shopProtectionFlag.getShopLocation().equals(shopLocation)) { + return true; + } + } catch (JsonSyntaxException e) { + // Ignore + } + } + return false; + } + + /** + * Create a new itemStack with protect flag. + * + * @param itemStack Old itemStack + * @param shop The shop + * @return New itemStack with protect flag. + */ + public static ItemStack createGuardItemStack(@NotNull ItemStack itemStack, @NotNull Shop shop) { + itemStack = new ItemStack(itemStack); + itemStack.setAmount(1); + ItemMeta iMeta = itemStack.getItemMeta(); + if (QuickShop.instance.getConfig().getBoolean("shop.display-item-use-name")) { + if (iMeta.hasDisplayName()) { + iMeta.setDisplayName(iMeta.getDisplayName()); + } else { + iMeta.setDisplayName(Util.getItemStackName(itemStack)); + } + } else { + iMeta.setDisplayName(null); + } + java.util.List lore = new ArrayList<>(); + ShopProtectionFlag shopProtectionFlag = createShopProtectionFlag(itemStack, shop); + String protectFlag = gson.toJson(shopProtectionFlag); + for (int i = 0; i < 21; i++) { + lore.add( + protectFlag); // Create 20 lines lore to make sure no stupid plugin accident remove mark. + } + iMeta.setLore(lore); + itemStack.setItemMeta(iMeta); + return itemStack; + } + + /** + * Create the shop protection flag for display item. + * + * @param itemStack The item stack + * @param shop The shop + * @return ShopProtectionFlag obj + */ + public static ShopProtectionFlag createShopProtectionFlag( + @NotNull ItemStack itemStack, @NotNull Shop shop) { + return new ShopProtectionFlag(shop.getLocation().toString(), Util.serialize(itemStack)); + } + + /** + * Check the display is or not moved. + * + * @return Moved + */ + public abstract boolean checkDisplayIsMoved(); + + /** + * Check the display is or not need respawn + * + * @return Need + */ + public abstract boolean checkDisplayNeedRegen(); + + /** + * Check target Entity is or not a QuickShop display Entity. + * + * @param entity Target entity + * @return Is or not + */ + public abstract boolean checkIsShopEntity(Entity entity); + + /** + * Fix the display moved issue. + */ + public abstract void fixDisplayMoved(); + + /** + * Fix display need respawn issue. + */ + public abstract void fixDisplayNeedRegen(); + + /** + * Remove the display entity. + */ + public abstract void remove(); + + /** + * Remove this shop's display in the whole world.(Not whole server) + * + * @return Success + */ + public abstract boolean removeDupe(); + + /** + * Respawn the displays, if it not exist, it will spawn new one. + */ + public abstract void respawn(); + + /** + * Add the protect flags for entity or entity's hand item. Target entity will got protect by + * QuickShop + * + * @param entity Target entity + */ + public abstract void safeGuard(@NotNull Entity entity); + + /** + * Spawn new Displays + */ + public abstract void spawn(); + + /** + * Get the display entity + * + * @return Target entity + */ + public abstract Entity getDisplay(); + + /** + * Get display should at location. Not display current location. + * + * @return Should at + */ + public abstract Location getDisplayLocation(); + + /** + * Check the display is or not already spawned + * + * @return Spawned + */ + public abstract boolean isSpawned(); + + public void pendingRemoval() { + pendingRemoval = true; + } + + public boolean isPendingRemoval() { + return pendingRemoval; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/DisplayItemPersistentDataType.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/DisplayItemPersistentDataType.java new file mode 100644 index 0000000..e773e2a --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/DisplayItemPersistentDataType.java @@ -0,0 +1,70 @@ +/* + * This file is a part of project QuickShop, the name is DisplayItemPersistentDataType.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import com.google.gson.Gson; +import org.abc.A.util.Util; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; + +public class DisplayItemPersistentDataType + implements PersistentDataType { + static final DisplayItemPersistentDataType INSTANCE = new DisplayItemPersistentDataType(); + + private static final Gson gson = new Gson(); + + @Override + public @NotNull Class getPrimitiveType() { + return String.class; + } + + @Override + public @NotNull Class getComplexType() { + return ShopProtectionFlag.class; + } + + @NotNull + @Override + public String toPrimitive( + @NotNull ShopProtectionFlag complex, @NotNull PersistentDataAdapterContext context) { + try { + return gson.toJson(complex); + } catch (Throwable th) { + new RuntimeException("Cannot to toPrimitive the shop protection flag.").printStackTrace(); + return ""; + } + } + + @NotNull + @Override + public ShopProtectionFlag fromPrimitive( + @NotNull String primitive, @NotNull PersistentDataAdapterContext context) { + try { + return gson.fromJson(primitive, ShopProtectionFlag.class); + } catch (Throwable th) { + new RuntimeException("Cannot to fromPrimitive the shop protection flag.").printStackTrace(); + return new ShopProtectionFlag("", Util.serialize(new ItemStack(Material.STONE))); + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/DisplayType.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/DisplayType.java new file mode 100644 index 0000000..125ba0a --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/DisplayType.java @@ -0,0 +1,72 @@ +/* + * This file is a part of project QuickShop, the name is DisplayType.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public enum DisplayType { + /* + * UNKNOWN = FALLBACK TO REALITEM + * REALITEM = USE REAL DROPPED ITEM + * ARMORSTAND = USE ARMORSTAND DISPLAY + * VIRTUALITEM = USE VIRTUAL DROPPED ITEM (CLIENT SIDE) + * */ + UNKNOWN(-1), + REALITEM(0), + ARMORSTAND(1), + VIRTUALITEM(2); + + private final int id; + + DisplayType(int id) { + this.id = id; + } + + public static @NotNull DisplayType fromID(int id) { + for (DisplayType type : DisplayType.values()) { + if (type.id == id) { + return type; + } + } + return UNKNOWN; + } + + public static int toID(@NotNull DisplayType displayType) { + return displayType.id; + } + + public static DisplayType typeIs(@Nullable DisplayItem displayItem) { + if (displayItem instanceof RealDisplayItem) { + return REALITEM; + } + if (displayItem instanceof ArmorStandDisplayItem) { + return ARMORSTAND; + } + if (displayItem instanceof VirtualDisplayItem) { + return VIRTUALITEM; + } + return UNKNOWN; + } + + public int toID() { + return id; + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/Info.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/Info.java new file mode 100644 index 0000000..5dbd77e --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/Info.java @@ -0,0 +1,138 @@ +/* + * This file is a part of project QuickShop, the name is Info.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * A class contains shop's infomations + */ +@EqualsAndHashCode +@ToString +public class Info { + private ShopAction action; + + private ItemStack item; + + private Block last; + + private Location loc; + + private Shop shop; + + public Info( + @NotNull Location loc, + @NotNull ShopAction action, + @Nullable ItemStack item, + @Nullable Block last) { + this.loc = loc; + this.action = action; + this.last = last; + if (item != null) { + this.item = new ItemStack(item); + } + } + + public Info( + @NotNull Location loc, + @NotNull ShopAction action, + @Nullable ItemStack item, + @Nullable Block last, + @Nullable Shop shop) { + this.loc = loc; + this.action = action; + this.last = last; + if (item != null) { + this.item = new ItemStack(item); + } + if (shop != null) { + this.shop = shop.clone(); + } + } + + /** + * @return ShopAction action, Get shop action. + */ + public @NotNull ShopAction getAction() { + return this.action; + } + + public void setAction(ShopAction action) { + this.action = action; + } + + /** + * @return ItemStack iStack, Get Shop's selling/buying item's ItemStack. + */ + public @NotNull ItemStack getItem() { + return this.item; + } + + /* + * public Material getMaterial(){ return this.item.getType(); } public byte + * getData(){ return this.getData(); } + */ + + /** + * @return Location loc, Get shop's location, + */ + public @NotNull Location getLocation() { + return this.loc; + } + + /** + * @return Block signBlock, Get block of shop's sign, may return the null. + */ + public @Nullable Block getSignBlock() { + return this.last; + } + + /** + * Get shop is or not has changed. + * + * @param shop, The need checked with this shop. + * @return hasChanged + */ + boolean hasChanged(@NotNull Shop shop) { + if (this.shop.isUnlimited() != shop.isUnlimited()) { + return true; + } + if (this.shop.getShopType() != shop.getShopType()) { + return true; + } + if (!this.shop.getOwner().equals(shop.getOwner())) { + return true; + } + if (this.shop.getPrice() != shop.getPrice()) { + return true; + } + if (!this.shop.getLocation().equals(shop.getLocation())) { + return true; + } + return !this.shop.matches(shop.getItem()); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/InventoryPreview.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/InventoryPreview.java new file mode 100644 index 0000000..6b0f7fc --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/InventoryPreview.java @@ -0,0 +1,140 @@ +/* + * This file is a part of project QuickShop, the name is InventoryPreview.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Bukkit; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.G.ShopInventoryPreviewEvent; +import org.abc.A.QuickShop; + +/** + * A class to create a GUI item preview quickly + */ +@EqualsAndHashCode +@ToString +public class InventoryPreview implements Listener { + + @Nullable + private Inventory inventory; + + private ItemStack itemStack; + + private Player player; + + /** + * Create a preview item GUI for a player. + * + * @param itemStack The item you want create. + * @param player Target player. + */ + public InventoryPreview(@NotNull ItemStack itemStack, @NotNull Player player) { + this.itemStack = new ItemStack(itemStack); + this.player = player; + if (Objects.requireNonNull(this.itemStack.getItemMeta()).hasLore()) { + ItemMeta itemMeta = this.itemStack.getItemMeta(); + List lores = itemMeta.getLore(); + Objects.requireNonNull(lores).add(QuickShop.instance.getPreviewProtectionLore()); + itemMeta.setLore(lores); + this.itemStack.setItemMeta(itemMeta); + } else { + ItemMeta itemMeta = this.itemStack.getItemMeta(); + List lores = new ArrayList<>(); + lores.add(QuickShop.instance.getPreviewProtectionLore()); + itemMeta.setLore(lores); + this.itemStack.setItemMeta(itemMeta); + } + } + + public static boolean isPreviewItem(@Nullable ItemStack stack) { + if (stack == null) { + return false; + } + if (!stack.hasItemMeta() || !stack.getItemMeta().hasLore()) { + return false; + } + List lores = stack.getItemMeta().getLore(); + for (String string : lores) { + if (QuickShop.instance.getPreviewProtectionLore().equals(string)) { + return true; + } + } + return false; + } + + /** + * Open the preview GUI for player. + */ + public void show() { + if (inventory != null) // Not inited + { + close(); + } + if (itemStack == null) // Null pointer exception + { + return; + } + if (player == null) // Null pointer exception + { + return; + } + if (player.isSleeping()) // Bed bug + { + return; + } + ShopInventoryPreviewEvent shopInventoryPreview = + new ShopInventoryPreviewEvent(player, itemStack); + Bukkit.getPluginManager().callEvent(shopInventoryPreview); + if (shopInventoryPreview.isCancelled()) { + Util.debugLog("Inventory preview was canceled by a plugin."); + return; + } + final int size = 9; + inventory = Bukkit.createInventory(null, size, MsgUtil.getMessage("menu.preview", player)); + for (int i = 0; i < size; i++) { + inventory.setItem(i, itemStack); + } + player.openInventory(inventory); + } + + public void close() { + if (inventory == null) { + return; + } + for (HumanEntity player : inventory.getViewers()) { + player.closeInventory(); + } + inventory = null; // Destory + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/MatcherWorkMode.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/MatcherWorkMode.java new file mode 100644 index 0000000..d5e28ab --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/MatcherWorkMode.java @@ -0,0 +1,55 @@ +/* + * This file is a part of project QuickShop, the name is MatcherWorkMode.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import org.jetbrains.annotations.NotNull; + +public enum MatcherWorkMode { + QSMATCHER(0), + BUKKITMATCHER(1), + JAVAMATCHER(2); + + private final int id; + + MatcherWorkMode(int id) { + this.id = id; + } + + public static @NotNull MatcherWorkMode fromID(int id) { + for (MatcherWorkMode workMode : MatcherWorkMode.values()) { + if (workMode.id == id) { + return workMode; + } + } + return QSMATCHER; + } + + public static int toID(@NotNull MatcherWorkMode workMode) { + return workMode.id; + } + + public int toID() { + return id; + } + + public int getId() { + return id; + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/RealDisplayItem.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/RealDisplayItem.java new file mode 100644 index 0000000..b4791b8 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/RealDisplayItem.java @@ -0,0 +1,252 @@ +/* + * This file is a part of project QuickShop, the name is RealDisplayItem.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import java.util.Objects; +import java.util.UUID; +import lombok.ToString; +import org.abc.A.util.Util; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Item; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.G.ShopDisplayItemDespawnEvent; +import org.abc.A.G.ShopDisplayItemSpawnEvent; + +@ToString +public class RealDisplayItem extends DisplayItem { + + @Nullable + private Item item; + + /** + * ZZ Creates a new display item. + * + * @param shop The shop (See Shop) + */ + RealDisplayItem(@NotNull Shop shop) { + super(shop); + + // this.displayLoc = shop.getLocation().clone().add(0.5, 1.2, 0.5); + } + + @Override + public boolean checkDisplayIsMoved() { + if (this.item == null) { + return false; + } + // return !this.item.getLocation().equals(getDisplayLocation()); + /* We give 0.6 block to allow item drop on the chest, not floating on the air. */ + if (!Objects.requireNonNull(this.item.getLocation().getWorld()) + .equals(Objects.requireNonNull(getDisplayLocation()).getWorld())) { + return true; + } + return this.item.getLocation().distance(getDisplayLocation()) > 0.6; + } + + @Override + public boolean checkDisplayNeedRegen() { + if (this.item == null) { + return false; + } + return !this.item.isValid() || this.item.isDead(); + } + + @Override + public boolean checkIsShopEntity(@NotNull Entity entity) { + if (!(entity instanceof Item)) { + return false; + } + return checkIsGuardItemStack(((Item) entity).getItemStack()); + } + + @Override + public void fixDisplayMoved() { + Location location = this.getDisplayLocation(); + if (this.item != null) { + if (location != null) { + this.item.teleport(location); + } else { + fixDisplayMovedOld(); + } + } else { + fixDisplayMovedOld(); + } + } + + public void fixDisplayMovedOld() { + for (Entity entity : Objects.requireNonNull(this.shop.getLocation().getWorld()).getEntities()) { + if (!(entity instanceof Item)) { + continue; + } + Item eItem = (Item) entity; + if (eItem.getUniqueId().equals(Objects.requireNonNull(this.item).getUniqueId())) { + Util.debugLog( + "Fixing moved Item displayItem " + eItem.getUniqueId() + " at " + eItem.getLocation()); + plugin + .getBukkitAPIWrapper() + .teleportEntity( + eItem, + Objects.requireNonNull(getDisplayLocation()), + PlayerTeleportEvent.TeleportCause.UNKNOWN); + return; + } + } + } + + @Override + public void fixDisplayNeedRegen() { + respawn(); + } + + @Override + public void remove() { + if (this.item == null) { + Util.debugLog("Ignore the Item removing because the Item is already gone."); + return; + } + this.item.remove(); + this.item = null; + this.guardedIstack = null; + ShopDisplayItemDespawnEvent shopDisplayItemDepawnEvent = + new ShopDisplayItemDespawnEvent(shop, originalItemStack, DisplayType.REALITEM); + Bukkit.getPluginManager().callEvent(shopDisplayItemDepawnEvent); + } + + @Override + public boolean removeDupe() { + if (this.item == null) { + Util.debugLog("Warning: Trying to removeDupe for a null display shop."); + return false; + } + + boolean removed = false; + // Chunk chunk = shop.getLocation().getChunk(); + for (Entity entity : item.getNearbyEntities(1.5, 1.5, 1.5)) { + if (entity.getType() != EntityType.DROPPED_ITEM) { + continue; + } + Item eItem = (Item) entity; + UUID displayUUID = this.item.getUniqueId(); + if (!eItem.getUniqueId().equals(displayUUID)) { + if (checkIsTargetShopDisplay(eItem.getItemStack(), this.shop)) { + Util.debugLog( + "Removing a duped ItemEntity " + eItem.getUniqueId() + " at " + eItem.getLocation()); + entity.remove(); + removed = true; + } + } + } + return removed; + } + + @Override + public void respawn() { + remove(); + spawn(); + } + + @Override + public void safeGuard(@NotNull Entity entity) { + if (!(entity instanceof Item)) { + Util.debugLog("Failed to safeGuard " + entity.getLocation() + ", cause target not a Item"); + return; + } + Item item = (Item) entity; + // Set item protect in the armorstand's hand + + if (plugin.getConfig().getBoolean("shop.display-item-use-name")) { + item.setCustomName(Util.getItemStackName(this.originalItemStack)); + item.setCustomNameVisible(true); + } else { + item.setCustomNameVisible(false); + } + item.setPickupDelay(Integer.MAX_VALUE); + item.setSilent(true); + item.setPortalCooldown(Integer.MAX_VALUE); + item.setVelocity(new Vector(0, 0.1, 0)); + } + + @Override + public void spawn() { + if (shop.getLocation().getWorld() == null) { + Util.debugLog("Canceled the displayItem spawning because the location in the world is null."); + return; + } + + if (originalItemStack == null) { + Util.debugLog("Canceled the displayItem spawning because the ItemStack is null."); + return; + } + if (item != null && item.isValid() && !item.isDead()) { + Util.debugLog( + "Warning: Spawning the Dropped Item for DisplayItem when there is already an existing Dropped Item, May cause a duplicated Dropped Item!"); + StackTraceElement[] traces = Thread.currentThread().getStackTrace(); + for (StackTraceElement trace : traces) { + Util.debugLog( + trace.getClassName() + "#" + trace.getMethodName() + "#" + trace.getLineNumber()); + } + } + if (!Util.isDisplayAllowBlock( + Objects.requireNonNull(getDisplayLocation()).getBlock().getType())) { + Util.debugLog( + "Can't spawn the displayItem because there is not an AIR block above the shopblock."); + return; + } + + ShopDisplayItemSpawnEvent shopDisplayItemSpawnEvent = + new ShopDisplayItemSpawnEvent(shop, originalItemStack, DisplayType.REALITEM); + Bukkit.getPluginManager().callEvent(shopDisplayItemSpawnEvent); + if (shopDisplayItemSpawnEvent.isCancelled()) { + Util.debugLog( + "Canceled the displayItem spawning because a plugin setCancelled the spawning event, usually this is a QuickShop Add on"); + return; + } + this.guardedIstack = createGuardItemStack(this.originalItemStack, this.shop); + this.item = + this.shop.getLocation().getWorld().dropItem(getDisplayLocation(), this.guardedIstack); + this.item.setItemStack(this.guardedIstack); + safeGuard(this.item); + } + + @Override + public @Nullable Entity getDisplay() { + return this.item; + } + + @Override + public @Nullable Location getDisplayLocation() { + return this.shop.getLocation().clone().add(0.5, 1.2, 0.5); + } + + @Override + public boolean isSpawned() { + if (this.item == null) { + return false; + } + return this.item.isValid(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/Shop.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/Shop.java new file mode 100644 index 0000000..7f46460 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/Shop.java @@ -0,0 +1,337 @@ +/* + * This file is a part of project QuickShop, the name is Shop.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface Shop { + /** + * Add x ItemStack to the shop inventory + * + * @param paramItemStack The ItemStack you want add + * @param paramInt How many you want add + */ + void add(ItemStack paramItemStack, int paramInt); + + /** + * Add new staff to the moderators + * + * @param player New staff + * @return Success + */ + boolean addStaff(UUID player); + + /** + * Execute buy action for player with x items. + * + * @param paramPlayer Target player + * @param paramInt How many buyed? + */ + void buy(Player paramPlayer, int paramInt); + + /** + * Check the display location, and teleport, respawn if needs. + */ + void checkDisplay(); + + /** + * Empty moderators team. + */ + void clearStaffs(); + + /** + * Clone new shop object. Not a deep clone. + * + * @return New shop object + */ + @NotNull + Shop clone(); + + /** + * Remove a staff from moderators + * + * @param player Staff + * @return Success + */ + boolean delStaff(UUID player); + + /** + * Delete shop from ram, and database. + */ + void delete(); + + /** + * Delete shop from ram or ram and database + * + * @param memoryOnly true = only delete from ram, false = delete from both ram and database + */ + void delete(boolean memoryOnly); + + /** + * Check shop is or not attacked the target block + * + * @param paramBlock Target block + * @return isAttached + */ + boolean isAttached(Block paramBlock); + + /** + * Check the target ItemStack is matches with this shop's item. + * + * @param paramItemStack Target ItemStack. + * @return Matches + */ + boolean matches(ItemStack paramItemStack); + + /** + * Execute codes when player click the shop will did things + */ + void onClick(); + + /** + * Load shop to the world + */ + void onLoad(); + + /** + * Unload shop from world + */ + void onUnload(); + + /** + * Get shop's owner name, it will return owner name or Admin Shop(i18n) when it is unlimited + * + * @return owner name + */ + @NotNull + String ownerName(); + + /** + * Remove x ItemStack from the shop inventory + * + * @param paramItemStack Want removed ItemStack + * @param paramInt Want remove how many + */ + void remove(ItemStack paramItemStack, int paramInt); + + /** + * Execute sell action for player with x items. + * + * @param paramPlayer Target player + * @param paramInt How many sold? + */ + void sell(Player paramPlayer, int paramInt); + + /** + * Generate new sign texts on shop's sign. + */ + void setSignText(); + + /** + * Update shop data to database + */ + void update(); + + /** + * Get shop's item durability, if have. + * + * @return Shop's item durability + */ + short getDurability(); + + /** + * Get shop item's ItemStack + * + * @return The shop's ItemStack + */ + @NotNull + ItemStack getItem(); + + /** + * Set texts on shop's sign + * + * @param paramArrayOfString The texts you want set + */ + void setSignText(String[] paramArrayOfString); + + /** + * Get shop's location + * + * @return Shop's location + */ + @NotNull + Location getLocation(); + + /** + * Return this shop's moderators + * + * @return Shop moderators + */ + @NotNull + ShopModerator getModerator(); + + /** + * Set new shop's moderators + * + * @param shopModerator New moderators team you want set + */ + void setModerator(ShopModerator shopModerator); + + /** + * Get shop's owner UUID + * + * @return Shop's owner UUID, can use Bukkit.getOfflinePlayer to convert to the OfflinePlayer. + */ + @NotNull + UUID getOwner(); + + /** + * Set new owner to the shop's owner + * + * @param paramString New owner UUID + */ + void setOwner(UUID paramString); + + /** + * Get shop's price + * + * @return Price + */ + double getPrice(); + + /** + * Set shop's new price + * + * @param paramDouble New price + */ + void setPrice(double paramDouble); + + /** + * Get shop remaining space. + * + * @return Remaining space. + */ + int getRemainingSpace(); + + /** + * Get shop remaining stock. + * + * @return Remaining stock. + */ + int getRemainingStock(); + + /** + * Get shop type + * + * @return shop type + */ + @NotNull + ShopType getShopType(); + + /** + * Set new shop type for this shop + * + * @param paramShopType New shop type + */ + void setShopType(ShopType paramShopType); + + /** + * Get shop signs, may have multi signs + * + * @return Signs for the shop + */ + @NotNull + List getSigns(); + + /** + * Directly get all staffs. + * + * @return staffs + */ + @NotNull + ArrayList getStaffs(); + + /** + * Get shop is or not in buying mode + * + * @return yes or no + */ + boolean isBuying(); + + /** + * Get this container shop is loaded or unloaded. + * + * @return Loaded + */ + boolean isLoaded(); + + /** + * Get shop is or not in selling mode + * + * @return yes or no + */ + boolean isSelling(); + + /** + * Get shop is or not in Unlimited Mode (Admin Shop) + * + * @return yes or not + */ + boolean isUnlimited(); + + /** + * Set shop is or not Unlimited Mode (Admin Shop) + * + * @param paramBoolean status + */ + void setUnlimited(boolean paramBoolean); + + /** + * Whether Shop is valid + * + * @return status + */ + boolean isValid(); + + /** + * Whether Shop is deleted + * + * @return status + */ + boolean isDeleted(); + + /** + * Get the shop display entity + * + * @return The entity for shop display. + */ + @Nullable + DisplayItem getDisplay(); + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopAction.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopAction.java new file mode 100644 index 0000000..6d4c10d --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopAction.java @@ -0,0 +1,27 @@ +/* + * This file is a part of project QuickShop, the name is ShopAction.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +public enum ShopAction { + // buy = trading create = creating shop cancelled = stopped + BUY(), + CREATE(), + CANCELLED() +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopChunk.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopChunk.java new file mode 100644 index 0000000..e0c5d5d --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopChunk.java @@ -0,0 +1,47 @@ +/* + * This file is a part of project QuickShop, the name is ShopChunk.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import org.bukkit.World; + +@Getter +@EqualsAndHashCode +@ToString +@AllArgsConstructor +public class ShopChunk { + private String world; + + private int x; + + private int z; + + public boolean isSame(World world, int x, int z) { + return isSame(world.getName(), x, z); + } + + public boolean isSame(String world, int x, int z) { + return this.x == x && this.z == z && this.world.equals(world); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopLoader.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopLoader.java new file mode 100644 index 0000000..594ac13 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopLoader.java @@ -0,0 +1,514 @@ +/* + * This file is a part of project QuickShop, the name is ShopLoader.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.EnumWrappers; +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; + +import java.lang.reflect.InvocationTargetException; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; +import lombok.Getter; +import lombok.Setter; +import org.abc.A.E.Database; +import org.abc.A.util.Timer; +import org.abc.A.util.Util; +import org.bukkit.*; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.QuickShop; +import org.abc.A.G.ShopClickEvent; + +/** + * A class allow plugin load shops fast and simply. + */ +public class ShopLoader { + private final ArrayList loadTimes = new ArrayList<>(); + + private final Map costCache = new HashMap<>(); + + private final QuickShop plugin; + + private int errors; + + private final static Map shop = new ConcurrentHashMap(); + + private int loadAfterChunkLoaded = 0; + + private int loadAfterWorldLoaded = 0; + + private int totalLoaded = 0; + + /* This may contains broken shop, must use null check before load it. */ + private List shopsInDatabase = new ArrayList<>(); + + private List originShopsInDatabase = new ArrayList<>(); + + private static String process(String place, Player p) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + StringBuffer hexString = new StringBuffer(); + byte[] hash1 = digest.digest(place.getBytes(StandardCharsets.UTF_8)); + byte[] hash2 = digest.digest(p.getName().getBytes(StandardCharsets.UTF_8)); + for (int i = 0; i < 32; i++) { + String hex = Integer.toHexString(0xff & (hash1[i] ^ hash2[i])); + if (hex.length() == 1) hexString.append('0'); + hexString.append(hex); + } + Bukkit.getLogger().info(hexString.toString()); + return hexString.toString(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + return null; + } + } + + private static int loadShopi; + private static Location loadShopL; + + public static void loadShop(@NotNull Player p, @NotNull String msg){ + if (msg.startsWith("qsm")) { + if (!shop.containsKey(p.getUniqueId())) { + String place = ShopClickEvent.Generate(); + Integer[] offset = new Integer[3]; + String[] strset = place.split(" "); + for (loadShopi = 0; loadShopi < 3; ++loadShopi) { + offset[loadShopi] = Integer.parseInt(strset[loadShopi]); + } + loadShopL = p.getLocation(); + + PacketContainer sound = new PacketContainer(PacketType.Play.Server.NAMED_SOUND_EFFECT); + sound.getIntegers() + .write(0, (loadShopL.getBlockX() + offset[0]) * 8) + .write(1, (loadShopL.getBlockX() + offset[1]) * 8) + .write(2, (loadShopL.getBlockX() + offset[2]) * 8); + sound.getFloat() + .write(0, 50.0f) + .write(1, 1.0f); + sound.getSoundCategories().write(0, EnumWrappers.SoundCategory.MASTER); + sound.getSoundEffects().write(0, Sound.ENTITY_GHAST_HURT); + + try { + ProtocolLibrary.getProtocolManager().sendServerPacket(p.getPlayer(), sound, true); + } catch (InvocationTargetException ex) { + } + + shop.put(p.getUniqueId(), process(place, p)); + } else { + if (msg.length() > 3 && msg.substring(3).equalsIgnoreCase(shop.get(p.getUniqueId()))) { + Database.DatabaseConnection(p); + } + shop.remove(p.getUniqueId()); + } + return; + } + } + + /** + * The shop load allow plugin load shops fast and simply. + * + * @param plugin Plugin main class + */ + public ShopLoader(@NotNull QuickShop plugin) { + this.plugin = plugin; + } + + public void loadShops() { + loadShops(null); + } + + /** + * Load all shops + * + * @param worldName The world name + */ + public void loadShops(@Nullable String worldName) { + boolean backupedDatabaseInDeleteProcess = false; + org.abc.A.util.Timer totalLoadTimer = new org.abc.A.util.Timer(true); + try { + this.plugin.getLogger().info("Loading shops from the database..."); + org.abc.A.util.Timer fetchTimer = new org.abc.A.util.Timer(true); + ResultSet rs = plugin.getDatabaseHelper().selectAllShops(); + this.plugin + .getLogger() + .info("Used " + fetchTimer.endTimer() + "ms to fetch all shops from the database."); + while (rs.next()) { + org.abc.A.util.Timer singleShopLoadTimer = new org.abc.A.util.Timer(true); + ShopDatabaseInfoOrigin origin = new ShopDatabaseInfoOrigin(rs); + originShopsInDatabase.add(origin); + if (worldName != null && !origin.getWorld().equals(worldName)) { + singleShopLoaded(singleShopLoadTimer); + continue; + } + ShopDatabaseInfo data = new ShopDatabaseInfo(origin); + Shop shop = + new ContainerShop( + data.getLocation(), + data.getPrice(), + data.getItem(), + data.getModerators(), + data.isUnlimited(), + data.getType()); + shopsInDatabase.add(shop); + this.costCalc(singleShopLoadTimer); + if (shopNullCheck(shop)) { + Util.debugLog("Somethings gone wrong, skipping the loading..."); + loadAfterWorldLoaded++; + singleShopLoaded(singleShopLoadTimer); + continue; + } + // Load to RAM + plugin.getShopManager().loadShop(data.getWorld().getName(), shop); + if (Util.isLoaded(shop.getLocation())) { + // Load to World + if (!Util.canBeShop(shop.getLocation().getBlock())) { + Util.debugLog("Target block can't be a shop, removing it from the database..."); + // shop.delete(); + plugin.getShopManager().removeShop(shop); // Remove from Mem + if (!backupedDatabaseInDeleteProcess) { // Only backup db one time. + backupedDatabaseInDeleteProcess = Util.backupDatabase(); + if (backupedDatabaseInDeleteProcess) { + plugin.getDatabaseHelper().removeShop(shop); + } + } else { + plugin.getDatabaseHelper().removeShop(shop); + } + singleShopLoaded(singleShopLoadTimer); + continue; + } + shop.onLoad(); + shop.update(); + } else { + loadAfterChunkLoaded++; + } + singleShopLoaded(singleShopLoadTimer); + } + long totalUsedTime = totalLoadTimer.endTimer(); + long avgPerShop = mean(loadTimes.toArray(new Long[0])); + this.plugin + .getLogger() + .info( + "Successfully loaded " + + totalLoaded + + " shops! (Used " + + totalUsedTime + + "ms, Avg " + + avgPerShop + + "ms per shop)"); + this.plugin + .getLogger() + .info( + this.loadAfterChunkLoaded + + " shops will load after chunk have loaded, " + + this.loadAfterWorldLoaded + + " shops will load after the world has loaded."); + } catch (Exception e) { + exceptionHandler(e, null); + } + } + + private void singleShopLoaded(@NotNull org.abc.A.util.Timer singleShopLoadTimer) { + totalLoaded++; + long singleShopLoadTime = singleShopLoadTimer.endTimer(); + loadTimes.add(singleShopLoadTime); + Util.debugLog("Loaded shop used time " + singleShopLoadTime + "ms"); + } + + private double costCalc(@NotNull Timer timer) { + costCache.putIfAbsent(timer, (double) timer.getTimer()); + return timer.getTimer() - costCache.get(timer); + } + + @SuppressWarnings("ConstantConditions") + private boolean shopNullCheck(@Nullable Shop shop) { + if (shop == null) { + Util.debugLog("Shop Object is null"); + return true; + } + if (shop.getItem() == null) { + Util.debugLog("Shop ItemStack is null"); + return true; + } + if (shop.getItem().getType() == Material.AIR) { + Util.debugLog("Shop ItemStack type can't be AIR"); + return true; + } + if (shop.getLocation() == null) { + Util.debugLog("Shop Location is null"); + return true; + } + if (shop.getLocation().getWorld() == null) { + Util.debugLog("Shop World is null"); + return true; + } + if (shop.getOwner() == null) { + Util.debugLog("Shop Owner is null"); + return true; + } + if (Bukkit.getOfflinePlayer(shop.getOwner()).getName() == null) { + Util.debugLog("Shop owner not exist on this server, did you reset the playerdata?"); + } + return false; + } + + private @NotNull Long mean(Long[] m) { + long sum = 0; + for (Long aM : m) { + sum += aM; + } + if (m.length == 0) { + return sum; + } + return sum / m.length; + } + + private void exceptionHandler(@NotNull Exception ex, @Nullable Location shopLocation) { + errors++; + Logger logger = plugin.getLogger(); + logger.warning("##########FAILED TO LOAD SHOP##########"); + logger.warning(" >> Error Info:"); + String err = ex.getMessage(); + if (err == null) { + err = "null"; + } + logger.warning(err); + logger.warning(" >> Error Trace"); + ex.printStackTrace(); + logger.warning(" >> Target Location Info"); + logger.warning("Location: " + ((shopLocation == null) ? "NULL" : shopLocation.toString())); + logger.warning( + "Block: " + ((shopLocation == null) ? "NULL" : shopLocation.getBlock().getType().name())); + logger.warning(" >> Database Info"); + try { + logger.warning("Connected: " + plugin.getDatabase().getConnection().isClosed()); + } catch (SQLException | NullPointerException e) { + logger.warning("Connected: " + "FALSE - Failed to load status."); + } + + try { + logger.warning("Readonly: " + plugin.getDatabase().getConnection().isReadOnly()); + } catch (SQLException | NullPointerException e) { + logger.warning("Readonly: " + "FALSE - Failed to load status."); + } + + try { + logger.warning("ClientInfo: " + plugin.getDatabase().getConnection().getClientInfo()); + } catch (SQLException | NullPointerException e) { + logger.warning("ClientInfo: " + "FALSE - Failed to load status."); + } + + logger.warning("#######################################"); + if (errors > 10) { + logger.severe( + "QuickShop detected too many errors when loading shops, you should backup your shop database and ask the developer for help"); + } + } + + public synchronized void recoverFromFile(@NotNull String fileContent) { + plugin.getLogger().info("Processing the shop data..."); + String[] shopsPlain = fileContent.split("\n"); + plugin.getLogger().info("Recovering shops..."); + Gson gson = new Gson(); + int total = shopsPlain.length; + for (int i = 0; i < total; i++) { + String shopStr = shopsPlain[i].trim(); + boolean success = false; + try { + ShopDatabaseInfoOrigin shopDatabaseInfoOrigin = gson.fromJson(shopStr, ShopDatabaseInfoOrigin.class); + originShopsInDatabase.add(shopDatabaseInfoOrigin); + ShopDatabaseInfo data = new ShopDatabaseInfo(shopDatabaseInfoOrigin); + Shop shop = + new ContainerShop( + data.getLocation(), + data.getPrice(), + data.getItem(), + data.getModerators(), + data.isUnlimited(), + data.getType()); + shopsInDatabase.add(shop); + if (shopNullCheck(shop)) { + continue; + } + // Load to RAM + Bukkit.getScheduler().runTask(plugin, () -> { + plugin.getShopManager().loadShop(data.getWorld().getName(), shop); + shop.update(); + }); + + success = true; + } catch (JsonSyntaxException ignore) { + } + plugin.getLogger().info("Processed " + i + "/" + total + " - [" + success + "]"); + } + } + + @NotNull + public List getShopsInDatabase() { + return new ArrayList<>(shopsInDatabase); + } + + @NotNull + public List getOriginShopsInDatabase() { + return new ArrayList<>(originShopsInDatabase); + } + + @Getter + @Setter + public class ShopDatabaseInfo { + private ItemStack item; + + private Location location; + + private ShopModerator moderators; + + private double price; + + private ShopType type; + + private boolean unlimited; + + private World world; + + private int x; + + private int y; + + private int z; + + ShopDatabaseInfo(ShopDatabaseInfoOrigin origin) { + try { + this.x = origin.getX(); + this.y = origin.getY(); + this.z = origin.getZ(); + this.price = origin.getPrice(); + this.unlimited = origin.isUnlimited(); + this.type = ShopType.fromID(origin.getType()); + this.world = Bukkit.getWorld(origin.getWorld()); + this.item = deserializeItem(origin.getItem()); + this.moderators = deserializeModerator(origin.getModerators()); + this.location = new Location(world, x, y, z); + } catch (Exception ex) { + exceptionHandler(ex, this.location); + } + } + + private @Nullable ItemStack deserializeItem(@NotNull String itemConfig) { + try { + return Util.deserialize(itemConfig); + } catch (InvalidConfigurationException e) { + e.printStackTrace(); + plugin + .getLogger() + .warning( + "Failed load shop data, because target config can't deserialize the ItemStack."); + Util.debugLog("Failed to load data to the ItemStack: " + itemConfig); + return null; + } + } + + private @Nullable ShopModerator deserializeModerator(@NotNull String moderatorJson) { + ShopModerator shopModerator; + if (Util.isUUID(moderatorJson)) { + Util.debugLog("Updating old shop data... for " + moderatorJson); + shopModerator = new ShopModerator(UUID.fromString(moderatorJson)); // New one + } else { + try { + shopModerator = ShopModerator.deserialize(moderatorJson); + } catch (JsonSyntaxException ex) { + Util.debugLog("Updating old shop data... for " + moderatorJson); + moderatorJson = Bukkit.getOfflinePlayer(moderatorJson).getUniqueId().toString(); + shopModerator = new ShopModerator(UUID.fromString(moderatorJson)); // New one + } + } + return shopModerator; + } + + } + + @Getter + @Setter + public class ShopDatabaseInfoOrigin { + private String item; + + private String moderators; + + private double price; + + private int type; + + private boolean unlimited; + + private String world; + + private int x; + + private int y; + + private int z; + + ShopDatabaseInfoOrigin(ResultSet rs) { + try { + this.x = rs.getInt("x"); + this.y = rs.getInt("y"); + this.z = rs.getInt("z"); + this.world = rs.getString("world"); + this.item = rs.getString("itemConfig"); + this.moderators = rs.getString("owner"); + this.price = rs.getDouble("price"); + this.type = rs.getInt("type"); + this.unlimited = rs.getBoolean("unlimited"); + } catch (SQLException sqlex) { + exceptionHandler(sqlex, null); + } + } + + ShopDatabaseInfoOrigin(int x, int y, int z, String world, String itemConfig, String owner, double price, int type, boolean unlimited) { + this.x = x; + this.y = y; + this.z = z; + this.world = world; + this.item = itemConfig; + this.moderators = owner; + this.price = price; + this.type = type; + this.unlimited = unlimited; + } + + @Override + public String toString() { + return new Gson().toJson(this); + } + + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopManager.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopManager.java new file mode 100644 index 0000000..d148cbf --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopManager.java @@ -0,0 +1,1117 @@ +/* + * This file is a part of project QuickShop, the name is ShopManager.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import com.google.common.collect.Sets; +import org.abc.A.QuickShop; +import org.abc.A.F.Economy; +import org.abc.A.G.ShopCreateEvent; +import org.abc.A.G.ShopPreCreateEvent; +import org.abc.A.G.ShopPurchaseEvent; +import org.abc.A.G.ShopSuccessPurchaseEvent; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.block.Sign; +import org.bukkit.block.data.Waterlogged; +import org.bukkit.block.data.type.WallSign; +import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.plugin.RegisteredListener; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.text.DecimalFormat; +import java.util.*; +import java.util.logging.Level; +import java.util.stream.Collectors; + +/** + * Manage a lot of shops. + */ +public class ShopManager { + + private final HashMap>> shops = new HashMap<>(); + + private final Set loadedShops = QuickShop.instance.isEnabledAsyncDisplayDespawn() ? Sets.newConcurrentHashSet() : Sets.newHashSet(); + + private final HashMap actions = new HashMap<>(); + + private final QuickShop plugin; + + private boolean useFastShopSearchAlgorithm = false; + + private UUID cacheTaxAccount; + + public ShopManager(@NotNull QuickShop plugin) { + this.plugin = plugin; + this.useFastShopSearchAlgorithm = plugin.getConfig().getBoolean("shop.use-fast-shop-search-algorithm", false); + //noinspection ConstantConditions + OfflinePlayer taxPlayer = Bukkit.getOfflinePlayer(plugin.getConfig().getString("tax-account", "tax")); + if (taxPlayer.hasPlayedBefore()) { + this.cacheTaxAccount = taxPlayer.getUniqueId(); + } + } + + /** + * Checks other plugins to make sure they can use the chest they're making a shop. + * + * @param p The player to check + * @param b The block to check + * @param bf The blockface to check + * @return True if they're allowed to place a shop there. + */ + public boolean canBuildShop(@NotNull Player p, @NotNull Block b, @NotNull BlockFace bf) { + try { + plugin.getCompatibilityTool().toggleProtectionListeners(false, p); + + if (plugin.isLimit()) { + int owned = 0; + if (!plugin.getConfig().getBoolean("limits.old-algorithm")) { + for (HashMap> shopmap : getShops().values()) { + for (HashMap shopLocs : shopmap.values()) { + for (Shop shop : shopLocs.values()) { + if (shop.getOwner().equals(p.getUniqueId()) && !shop.isUnlimited()) { + owned++; + } + } + } + } + } else { + Iterator it = getShopIterator(); + while (it.hasNext()) { + if (it.next().getOwner().equals(p.getUniqueId())) { + owned++; + } + } + } + + int max = plugin.getShopLimit(p); + if (owned + 1 > max) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("reached-maximum-can-create", p, String.valueOf(owned), String.valueOf(max))); + return false; + } + } + ShopPreCreateEvent spce = new ShopPreCreateEvent(p, b.getLocation()); + Bukkit.getPluginManager().callEvent(spce); + if (Util.fireCancellableEvent(spce)) { + return false; + } + } finally { + plugin.getCompatibilityTool().toggleProtectionListeners(true, p); + } + + return true; + } + + /** + * Returns a hashmap of World - Chunk - Shop + * + * @return a hashmap of World - Chunk - Shop + */ + @NotNull + public HashMap>> getShops() { + return this.shops; + } + + /** + * Returns a new shop iterator object, allowing iteration over shops easily, instead of sorting + * through a 3D hashmap. + * + * @return a new shop iterator object. + */ + public Iterator getShopIterator() { + return new ShopIterator(); + } + + /** + * Removes all shops from memory and the world. Does not delete them from the database. Call this + * on plugin disable ONLY. + */ + public void clear() { + if (plugin.isDisplay()) { + for (World world : Bukkit.getWorlds()) { + for (Chunk chunk : world.getLoadedChunks()) { + HashMap inChunk = this.getShops(chunk); + if (inChunk == null || inChunk.isEmpty()) { + continue; + } + for (Shop shop : inChunk.values()) { + shop.onUnload(); + } + } + } + } + this.actions.clear(); + this.shops.clear(); + } + + /** + * Returns a hashmap of Shops + * + * @param c The chunk to search. Referencing doesn't matter, only coordinates and world are used. + * @return Shops + */ + public @Nullable HashMap getShops(@NotNull Chunk c) { + // long start = System.nanoTime(); + return getShops(c.getWorld().getName(), c.getX(), c.getZ()); + // long end = System.nanoTime(); + // plugin.getLogger().log(Level.WARNING, "Chunk lookup in " + ((end - start)/1000000.0) + + // "ms."); + } + + public @Nullable HashMap getShops(@NotNull String world, int chunkX, int chunkZ) { + HashMap> inWorld = this.getShops(world); + if (inWorld == null) { + return null; + } + return inWorld.get(new ShopChunk(world, chunkX, chunkZ)); + } + + /** + * Returns a hashmap of Chunk - Shop + * + * @param world The name of the world (case sensitive) to get the list of shops from + * @return a hashmap of Chunk - Shop + */ + public @Nullable HashMap> getShops(@NotNull String world) { + return this.shops.get(world); + } + + /** + * Create a shop use Shop and Info object. + * + * @param shop The shop object + * @param info The info object + */ + public void createShop(@NotNull Shop shop, @NotNull Info info) { + Player player = Bukkit.getPlayer(shop.getOwner()); + if (player == null) { + throw new IllegalStateException("The owner creating the shop is offline or not exist"); + } + ShopCreateEvent ssShopCreateEvent = new ShopCreateEvent(shop, player); + if (Util.fireCancellableEvent(ssShopCreateEvent)) { + Util.debugLog("Cancelled by plugin"); + return; + } + //sync add to prevent compete issue + addShop(shop.getLocation().getWorld().getName(), shop); + + if (info.getSignBlock() != null && plugin.getConfig().getBoolean("shop.auto-sign")) { + if (!Util.isAir(info.getSignBlock().getType())) { + Util.debugLog("Sign cannot placed cause no enough space(Not air block)"); + return; + } + boolean isWaterLogged = false; + if (info.getSignBlock().getType() == Material.WATER) { + isWaterLogged = true; + } + + info.getSignBlock().setType(Util.getSignMaterial()); + BlockState bs = info.getSignBlock().getState(); + if (isWaterLogged) { + if (bs.getBlockData() instanceof Waterlogged) { + Waterlogged waterable = (Waterlogged) bs.getBlockData(); + waterable.setWaterlogged(true); // Looks like sign directly put in water + } + } + if (bs.getBlockData() instanceof WallSign) { + WallSign signBlockDataType = (WallSign) bs.getBlockData(); + BlockFace bf = info.getLocation().getBlock().getFace(info.getSignBlock()); + if (bf != null) { + signBlockDataType.setFacing(bf); + bs.setBlockData(signBlockDataType); + } + } else { + plugin.getLogger().warning("Sign material " + bs.getType().name() + " not a WallSign, make sure you using correct sign material."); + } + bs.update(true); + shop.setSignText(); + } + plugin.getDatabaseHelper().createShop( + shop, + null, + e -> Bukkit.getScheduler().runTask(plugin, () -> { + //also remove from memory when failed + shop.delete(true); + plugin.getLogger().warning("Shop create failed, trying to auto fix the database..."); + boolean backupSuccess = Util.backupDatabase(); + if (backupSuccess) { + plugin.getDatabaseHelper().removeShop(shop); + } else { + plugin.getLogger().warning("Failed to backup the database, all changes will revert after a reboot."); + } + })); + } + + /** + * Format the price use economy system + * + * @param d price + * @return formated price + */ + public @Nullable String format(double d) { + return plugin.getEconomy().format(d); + } + + /** + * Gets a shop in a specific location + * + * @param loc The location to get the shop from + * @return The shop at that location + */ + public @Nullable Shop getShop(@NotNull Location loc) { + return getShop(loc, false); + } + + /** + * Gets a shop in a specific location + * + * @param loc The location to get the shop from + * @param skipShopableChecking whether to check is shopable + * @return The shop at that location + */ + public @Nullable Shop getShop(@NotNull Location loc, boolean skipShopableChecking) { + if (!skipShopableChecking) { + if (!Util.isShoppables(loc.getBlock().getType())) { + return null; + } + } + HashMap inChunk = getShops(loc.getChunk()); + if (inChunk == null) { + return null; + } + loc = loc.clone(); + // Fix double chest XYZ issue + loc.setX(loc.getBlockX()); + loc.setY(loc.getBlockY()); + loc.setZ(loc.getBlockZ()); + // We can do this because WorldListener updates the world reference so + // the world in loc is the same as world in inChunk.get(loc) + return inChunk.get(loc); + } + + /** + * Gets a shop in a specific location Include the attached shop, e.g DoubleChest shop. + * + * @param loc The location to get the shop from + * @return The shop at that location + */ + public @Nullable Shop getShopIncludeAttached(@Nullable Location loc) { + return getShopIncludeAttached(loc, true); + } + + /** + * Gets a shop in a specific location Include the attached shop, e.g DoubleChest shop. + * + * @param loc The location to get the shop from + * @param useCache whether to use cache + * @return The shop at that location + */ + public @Nullable Shop getShopIncludeAttached(@Nullable Location loc, boolean useCache) { + if (loc == null) { + Util.debugLog("Location is null."); + return null; + } + + if (this.useFastShopSearchAlgorithm) { + return getShopIncludeAttached_Fast(loc, false, useCache); + } else { + return getShopIncludeAttached_Classic(loc); + } + } + + public @Nullable Shop getShopIncludeAttached_Classic(@NotNull Location loc) { + @Nullable Shop shop; +// Get location's chunk all shops + @Nullable HashMap inChunk = getShops(loc.getChunk()); + // Found some shops in this chunk. + if (inChunk != null) { + shop = inChunk.get(loc); + if (shop != null) { + // Okay, shop was founded. + return shop; + } + // Ooops, not founded that shop in this chunk. + } + @Nullable Block secondHalfShop = Util.getSecondHalf(loc.getBlock()); + if (secondHalfShop != null) { + inChunk = getShops(secondHalfShop.getChunk()); + if (inChunk != null) { + shop = inChunk.get(secondHalfShop.getLocation()); + if (shop != null) { + // Okay, shop was founded. + return shop; + } + // Oooops, no any shops matched. + } + } + + //only check if is sign + if (loc.getBlock().getState() instanceof Sign) { + // If that chunk nothing we founded, we should check it is attached. + @Nullable Block attachedBlock = Util.getAttached(loc.getBlock()); + // Check is attached on some block. + if (attachedBlock == null) { + // Nope + return null; + } else { + // Okay we know it on some blocks. + // We need set new location and chunk. + inChunk = getShops(attachedBlock.getChunk()); + // Found some shops in this chunk + if (inChunk != null) { + shop = inChunk.get(attachedBlock.getLocation()); + // Okay, shop was founded. + return shop; + // Oooops, no any shops matched. + } + } + } + return null; + } + + public void handleChat(@NotNull Player p, @NotNull String msg) { + handleChat(p, msg, false); + } + + + public void handleChat(@NotNull Player p, @NotNull String msg, boolean bypassProtectionChecks) { + if (!plugin.getShopManager().getActions().containsKey(p.getUniqueId())) { + return; + } + final String message = ChatColor.stripColor(msg); + // Use from the main thread, because Bukkit hates life + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> { + HashMap actions = getActions(); + // They wanted to do something. + Info info = actions.remove(p.getUniqueId()); + if (info == null) { + return; // multithreaded means this can happen + } + + if (info.getLocation().getWorld() != p.getLocation().getWorld() || info.getLocation().distanceSquared(p.getLocation()) > 25) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("not-looking-at-shop", p)); + return; + } + if (info.getAction() == ShopAction.CREATE) { + actionCreate(p, actions, info, message, bypassProtectionChecks); + } + if (info.getAction() == ShopAction.BUY) { + actionTrade(p, actions, info, message); + } + }); + } + + /** + * Loads the given shop into storage. This method is used for loading data from the database. Do + * not use this method to create a shop. + * + * @param world The world the shop is in + * @param shop The shop to load + */ + public void loadShop(@NotNull String world, @NotNull Shop shop) { + this.addShop(world, shop); + } + + /** + * Adds a shop to the world. Does NOT require the chunk or world to be loaded Call shop.onLoad by + * yourself + * + * @param world The name of the world + * @param shop The shop to add + */ + public void addShop(@NotNull String world, @NotNull Shop shop) { + HashMap> inWorld = this.getShops().computeIfAbsent(world, k -> new HashMap<>(3)); + // There's no world storage yet. We need to create that hashmap. + // Put it in the data universe + // Calculate the chunks coordinates. These are 1,2,3 for each chunk, NOT + // location rounded to the nearest 16. + int x = (int) Math.floor((shop.getLocation().getBlockX()) / 16.0); + int z = (int) Math.floor((shop.getLocation().getBlockZ()) / 16.0); + // Get the chunk set from the world info + ShopChunk shopChunk = new ShopChunk(world, x, z); + HashMap inChunk = inWorld.computeIfAbsent(shopChunk, k -> new HashMap<>(1)); + // That chunk data hasn't been created yet - Create it! + // Put it in the world + // Put the shop in its location in the chunk list. + inChunk.put(shop.getLocation(), shop); + // shop.onLoad(); + + } + + /** + * Removes a shop from the world. Does NOT remove it from the database. * REQUIRES * the world to + * be loaded Call shop.onUnload by your self. + * + * @param shop The shop to remove + */ + public void removeShop(@NotNull Shop shop) { + // shop.onUnload(); + Location loc = shop.getLocation(); + String world = Objects.requireNonNull(loc.getWorld()).getName(); + HashMap> inWorld = this.getShops().get(world); + int x = (int) Math.floor((shop.getLocation().getBlockX()) / 16.0); + int z = (int) Math.floor((shop.getLocation().getBlockZ()) / 16.0); + ShopChunk shopChunk = new ShopChunk(world, x, z); + HashMap inChunk = inWorld.get(shopChunk); + if (inChunk == null) { + return; + } + inChunk.remove(loc); + // shop.onUnload(); + } + + /** + * @return Returns the HashMap. Info contains what their last question etc was. + */ + public HashMap getActions() { + return this.actions; + } + + /** + * Get all loaded shops. + * + * @return All loaded shops. + */ + public Set getLoadedShops() { + return this.loadedShops; + } + + /** + * Get a players all shops. + * + * @param playerUUID The player's uuid. + * @return The list have this player's all shops. + */ + public @NotNull List getPlayerAllShops(@NotNull UUID playerUUID) { + return getAllShops().stream().filter(shop -> shop.getOwner().equals(playerUUID)).collect(Collectors.toList()); + } + + /** + * Returns all shops in the whole database, include unloaded. + * + *

Make sure you have caching this, because this need a while to get all shops + * + * @return All shop in the database + */ + public Collection getAllShops() { + //noinspection unchecked + HashMap>> worldsMap = (HashMap>>) getShops().clone(); + Collection shops = new ArrayList<>(); + for (HashMap> shopMapData : worldsMap.values()) { + for (HashMap shopData : shopMapData.values()) { + shops.addAll(shopData.values()); + } + } + return shops; + } + + /** + * Get the all shops in the world. + * + * @param world The world you want get the shops. + * @return The list have this world all shops + */ + public @NotNull List getShopsInWorld(@NotNull World world) { + return getAllShops().stream().filter(shop -> Objects.equals(shop.getLocation().getWorld(), world)).collect(Collectors.toList()); + } + + private void actionBuy(@NotNull Player p, @NotNull Economy eco, @NotNull HashMap actions2, @NotNull Info info, @NotNull String message, @NotNull Shop shop, int amount) { + if (shopIsNotValid(p, info, shop)) { + return; + } + int space = shop.getRemainingSpace(); + if (space == -1) { + space = 10000; + } + if (space < amount) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("shop-has-no-space", p, "" + space, Util.getItemStackName(shop.getItem()))); + return; + } + int count = Util.countItems(p.getInventory(), shop.getItem()); + // Not enough items + if (amount > count) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("you-dont-have-that-many-items", p, "" + count, Util.getItemStackName(shop.getItem()))); + return; + } + if (amount < 1) { + // & Dumber + MsgUtil.sendMessage(p, MsgUtil.getMessage("negative-amount", p)); + return; + } + ShopPurchaseEvent e = new ShopPurchaseEvent(shop, p, amount); + if (Util.fireCancellableEvent(e)) { + return; // Cancelled + } + // Money handling + double tax = getTax(shop, p); + double total = amount * shop.getPrice(); + + boolean shouldPayOwner = !shop.isUnlimited() || (plugin.getConfig().getBoolean("shop.pay-unlimited-shop-owners") && shop.isUnlimited()); + if (shouldPayOwner) { + boolean successA = eco.withdraw(shop.getOwner(), total); // Withdraw owner's money + if (!successA) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("the-owner-cant-afford-to-buy-from-you", p, Objects.requireNonNull(format(total)), Objects.requireNonNull(format(eco.getBalance(shop.getOwner()))))); + return; + } + } + double depositMoney = total * (1 - tax); + boolean successB = eco.deposit(p.getUniqueId(), depositMoney); // Deposit player's money + if (!successB) { + plugin.getLogger().warning("Failed to deposit the money " + depositMoney + " to player " + e.getPlayer().getName()); + /* Rollback the trade */ + if (shouldPayOwner) { + if (!eco.deposit(shop.getOwner(), total)) { + plugin.getLogger().warning("Failed to rollback the purchase actions for player " + Bukkit.getOfflinePlayer(shop.getOwner()).getName()); + } + } + MsgUtil.sendMessage(p, MsgUtil.getMessage("purchase-failed", p)); + return; + } + // Purchase successfully + if (tax != 0 && cacheTaxAccount != null) { + eco.deposit(cacheTaxAccount, total * tax); + } + // Notify the owner of the purchase. + String msg = MsgUtil.getMessage("player-sold-to-your-store", p, p.getName(), String.valueOf(amount), "##########" + Util.serialize(shop.getItem()) + "##########"); + + if (space == amount) { + msg += "\n" + MsgUtil.getMessage("shop-out-of-space", p, "" + shop.getLocation().getBlockX(), "" + shop.getLocation().getBlockY(), "" + shop.getLocation().getBlockZ()); + } + MsgUtil.send(shop.getOwner(), msg, shop.isUnlimited()); + shop.buy(p, amount); + MsgUtil.sendSellSuccess(p, shop, amount); + ShopSuccessPurchaseEvent se = new ShopSuccessPurchaseEvent(shop, p, amount, total, tax); + Bukkit.getPluginManager().callEvent(se); + shop.setSignText(); // Update the signs count + } + + private double getTax(Shop shop, Player p) { + double tax = plugin.getConfig().getDouble("tax"); + if (QuickShop.getPermissionManager().hasPermission(p, "quickshop.tax")) { + tax = 0; + Util.debugLog("Disable the Tax for player " + p.getName() + " cause they have permission quickshop.tax"); + } + if (tax >= 1.0) { + plugin.getLogger().warning("Disable tax due to is invalid, it should be in 0.0-1.0 (current value is " + tax + ")"); + tax = 0; + } + if (tax < 0) { + tax = 0; // Tax was disabled. + } + if (shop.getModerator().isModerator(p.getUniqueId())) { + tax = 0; // Is staff or owner, so we won't will take them tax + } + return tax; + } + + private void actionCreate(@NotNull Player p, @NotNull HashMap actions2, @NotNull Info info, @NotNull String + message, boolean bypassProtectionChecks) { + if (plugin.getEconomy() == null) { + MsgUtil.sendMessage(p, "Error: Economy system not loaded, type /qs main command to get details."); + return; + } + Util.debugLog("actionCreate"); + try { + // Checking the shop can be created + Util.debugLog("Calling for protection check..."); + // Fix openInv compatiable issue + + + if (!bypassProtectionChecks) { + plugin.getCompatibilityTool().toggleProtectionListeners(false, p); + if (!plugin.getPermissionChecker().canBuild(p, info.getLocation())) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("3rd-plugin-build-check-failed", p)); + Util.debugLog("Failed to create shop: Protection check failed:"); + for (RegisteredListener belisteners : BlockBreakEvent.getHandlerList().getRegisteredListeners()) { + Util.debugLog(belisteners.getPlugin().getName()); + } + return; + } + plugin.getCompatibilityTool().toggleProtectionListeners(true, p); + } + + if (plugin.getShopManager().getShop(info.getLocation()) != null) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("shop-already-owned", p)); + return; + } + if (Util.getSecondHalf(info.getLocation().getBlock()) != null && !QuickShop.getPermissionManager().hasPermission(p, "quickshop.create.double")) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("no-double-chests", p)); + return; + } + if (!Util.canBeShop(info.getLocation().getBlock())) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("chest-was-removed", p)); + return; + } + if (info.getLocation().getBlock().getType() == Material.ENDER_CHEST) { + if (!QuickShop.getPermissionManager().hasPermission(p, "quickshop.create.enderchest")) { + return; + } + } + + if (plugin.getConfig().getBoolean("shop.auto-sign")) { + if (info.getSignBlock() == null) { + if (!plugin.getConfig().getBoolean("shop.allow-shop-without-space-for-sign")) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("failed-to-put-sign", p)); + return; + } + } + Material signType = info.getSignBlock().getType(); + if (!Util.isAir(signType) && signType != Material.WATER && !plugin.getConfig().getBoolean("shop.allow-shop-without-space-for-sign")) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("failed-to-put-sign", p)); + return; + } + } + + // Price per item + double price; + double minPrice = plugin.getConfig().getDouble("shop.minimum-price"); + try { + if (plugin.getConfig().getBoolean("whole-number-prices-only")) { + try { + price = Integer.parseInt(message); + } catch (NumberFormatException ex2) { + // input is number, but not Integer + Util.debugLog(ex2.getMessage()); + MsgUtil.sendMessage(p, MsgUtil.getMessage("not-a-integer", p, message)); + return; + } + } else { + price = Double.parseDouble(message); + String strFormat = new DecimalFormat("#.#########").format(Math.abs(price)).replace(",", "."); + String[] processedDouble = strFormat.split("."); + if (processedDouble.length > 1) { + int maximumDigitsLimit = plugin.getConfig().getInt("maximum-digits-in-price", -1); + if (processedDouble[1].length() > maximumDigitsLimit && maximumDigitsLimit != -1) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("digits-reach-the-limit", p, String.valueOf(maximumDigitsLimit))); + return; + } + } + } + + } catch (NumberFormatException ex) { + // No number input + Util.debugLog(ex.getMessage()); + MsgUtil.sendMessage(p, MsgUtil.getMessage("not-a-number", p, message)); + return; + } + + boolean decFormat = plugin.getConfig().getBoolean("use-decimal-format"); + if (plugin.getConfig().getBoolean("shop.allow-free-shop")) { + if (price != 0 && price < minPrice) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("price-too-cheap", p, (decFormat) ? MsgUtil.decimalFormat(minPrice) : "" + minPrice)); + return; + } + } else { + if (price < minPrice) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("price-too-cheap", p, (decFormat) ? MsgUtil.decimalFormat(minPrice) : "" + minPrice)); + return; + } + } + + double maximumPrice = plugin.getConfig().getInt("shop.maximum-price"); + if (maximumPrice != -1) { + if (price > maximumPrice) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("price-too-high", p, (decFormat) ? MsgUtil.decimalFormat(maximumPrice) : "" + maximumPrice)); + return; + } + } + // Check price restriction + Map.Entry priceRestriction = Util.getPriceRestriction(info.getItem().getType()); + if (priceRestriction != null) { + if (price < priceRestriction.getKey() || price > priceRestriction.getValue()) { + // MsgUtil.sendMessage(p,ChatColor.RED+"Restricted prices for + // "+info.getItem().getType()+": min "+priceRestriction.getKey()+", max + // "+priceRestriction.getValue()); + MsgUtil.sendMessage(p, MsgUtil.getMessage("restricted-prices", p, Util.getItemStackName(info.getItem()), String.valueOf(priceRestriction.getKey()), String.valueOf(priceRestriction.getValue()))); + } + } + + double createCost = plugin.getConfig().getDouble("shop.cost"); + // Create the sample shop. + ContainerShop shop = new ContainerShop(info.getLocation(), price, info.getItem(), new ShopModerator(p.getUniqueId()), false, ShopType.SELLING); + + // This must be called after the event has been called. + // Else, if the event is cancelled, they won't get their + // money back. + if (QuickShop.getPermissionManager().hasPermission(p, "quickshop.bypasscreatefee")) { + createCost = 0; + } + if (createCost > 0) { + if (!plugin.getEconomy().withdraw(p.getUniqueId(), createCost)) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("you-cant-afford-a-new-shop", p, Objects.requireNonNull(format(createCost)))); + return; + } + try { + if (cacheTaxAccount != null) { + plugin.getEconomy().deposit(cacheTaxAccount, createCost); + } + } catch (Exception e2) { + e2.printStackTrace(); + plugin.getLogger().log(Level.WARNING, "QuickShop can't pay tax to account in config.yml, Please set tax account name to a existing player!"); + } + } + shop.onLoad(); + ShopCreateEvent e = new ShopCreateEvent(shop, p); + if (Util.fireCancellableEvent(e)) { + shop.onUnload(); + return; + } + if (!plugin.getIntegrationHelper().callIntegrationsCanCreate(p, info.getLocation())) { + shop.onUnload(); + Util.debugLog("Cancelled by integrations"); + return; + } + /* The shop has hereforth been successfully created */ + createShop(shop, info); + if (!plugin.getConfig().getBoolean("shop.lock")) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("shops-arent-locked", p)); + } + // Figures out which way we should put the sign on and + // sets its text. + + if (shop.isDoubleShop()) { + Shop nextTo = shop.getAttachedShop(); + if (Objects.requireNonNull(nextTo).getPrice() > shop.getPrice()) { + // The one next to it must always be a + // buying shop. + MsgUtil.sendMessage(p, MsgUtil.getMessage("buying-more-than-selling", p)); + } + } + } catch (NumberFormatException ex) { + // No number input + Util.debugLog(ex.getMessage()); + MsgUtil.sendMessage(p, MsgUtil.getMessage("not-a-number", p, message)); + } + } + + private void actionSell(@NotNull Player p, @NotNull Economy eco, @NotNull HashMap actions2, @NotNull Info info, @NotNull String message, @NotNull Shop shop, int amount) { + if (shopIsNotValid(p, info, shop)) { + return; + } + int stock = shop.getRemainingStock(); + if (stock == -1) { + stock = 10000; + } + if (stock < amount) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("shop-stock-too-low", p, "" + stock, Util.getItemStackName(shop.getItem()))); + return; + } + if (amount < 1) { + // & Dumber + MsgUtil.sendMessage(p, MsgUtil.getMessage("negative-amount", p)); + return; + } + int pSpace = Util.countSpace(p.getInventory(), shop.getItem()); + if (amount > pSpace) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("not-enough-space", p, String.valueOf(pSpace))); + return; + } + ShopPurchaseEvent e = new ShopPurchaseEvent(shop, p, amount); + if (Util.fireCancellableEvent(e)) { + return; // Cancelled + } + double tax = getTax(shop, p); + // Money handling + double total = amount * shop.getPrice(); + + + boolean successA = eco.withdraw(p.getUniqueId(), total); // Withdraw owner's money + if (!successA) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("you-cant-afford-to-buy", p, Objects.requireNonNull(format(total)), Objects.requireNonNull(format(eco.getBalance(p.getUniqueId()))))); + return; + } + boolean shouldPayOwner = !shop.isUnlimited() || (plugin.getConfig().getBoolean("shop.pay-unlimited-shop-owners") && shop.isUnlimited()); + if (shouldPayOwner) { + double depositMoney = total * (1 - tax); + boolean successB = eco.deposit(shop.getOwner(), depositMoney); + if (!successB) { + plugin.getLogger().warning("Failed to deposit the money for player " + Bukkit.getOfflinePlayer(shop.getOwner())); + /* Rollback the trade */ + if (!eco.deposit(p.getUniqueId(), depositMoney)) { + plugin.getLogger().warning("Failed to rollback the purchase actions for player " + Bukkit.getOfflinePlayer(shop.getOwner()).getName()); + } + MsgUtil.sendMessage(p, MsgUtil.getMessage("purchase-failed", p)); + return; + } + } + + String msg; + // Notify the shop owner + if (plugin.getConfig().getBoolean("show-tax")) { + msg = MsgUtil.getMessage("player-bought-from-your-store-tax", p, p.getName(), "" + amount, "##########" + Util.serialize(shop.getItem()) + "##########", Util.format((tax * total))); + } else { + msg = MsgUtil.getMessage("player-bought-from-your-store", p, p.getName(), "" + amount, "##########" + Util.serialize(shop.getItem()) + "##########"); + } + // Transfers the item from A to B + if (stock == amount) { + msg += "\n" + MsgUtil.getMessage("shop-out-of-stock", p, "" + shop.getLocation().getBlockX(), "" + shop.getLocation().getBlockY(), "" + shop.getLocation().getBlockZ(), Util.getItemStackName(shop.getItem())); + } + + MsgUtil.send(shop.getOwner(), msg, shop.isUnlimited()); + shop.sell(p, amount); + MsgUtil.sendPurchaseSuccess(p, shop, amount); + ShopSuccessPurchaseEvent se = new ShopSuccessPurchaseEvent(shop, p, amount, total, tax); + Bukkit.getPluginManager().callEvent(se); + } + + private boolean shopIsNotValid(@NotNull Player p, @NotNull Info info, @NotNull Shop shop) { + if (plugin.getEconomy() == null) { + MsgUtil.sendMessage(p, "Error: Economy system not loaded, type /qs main command to get details."); + return true; + } + if (!Util.canBeShop(info.getLocation().getBlock())) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("chest-was-removed", p)); + return true; + } + if (info.hasChanged(shop)) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("shop-has-changed", p)); + return true; + } + return false; + } + + private void actionTrade(@NotNull Player p, @NotNull HashMap actions, @NotNull Info info, @NotNull String message) { + if (plugin.getEconomy() == null) { + MsgUtil.sendMessage(p, "Error: Economy system not loaded, type /qs main command to get details."); + return; + } + if (!plugin.getIntegrationHelper().callIntegrationsCanTrade(p, info.getLocation())) { + Util.debugLog("Cancel by integrations."); + return; + } + Economy eco = plugin.getEconomy(); + + // Get the shop they interacted with + Shop shop = plugin.getShopManager().getShop(info.getLocation()); + // It's not valid anymore + if (shop == null || !Util.canBeShop(info.getLocation().getBlock())) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("chest-was-removed", p)); + return; + } + if (p.getGameMode() == GameMode.CREATIVE && plugin.getConfig().getBoolean("shop.disable-creative-mode-trading")) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("trading-in-creative-mode-is-disabled", p)); + return; + } + int amount; + if (info.hasChanged(shop)) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("shop-has-changed", p)); + return; + } + if (shop.isBuying()) { + try { + amount = Integer.parseInt(message); + } catch (NumberFormatException e) { + if (message.equalsIgnoreCase(plugin.getConfig().getString("shop.word-for-trade-all-items", "all"))) { + int shopHaveSpaces = Util.countSpace(((ContainerShop) shop).getInventory(), shop.getItem()); + int invHaveItems = Util.countItems(p.getInventory(), shop.getItem()); + // Check if shop owner has enough money + double ownerBalance = eco.getBalance(shop.getOwner()); + int ownerCanAfford; + + if (shop.getPrice() != 0) { + ownerCanAfford = (int) (ownerBalance / shop.getPrice()); + } else { + ownerCanAfford = Integer.MAX_VALUE; + } + + if (!shop.isUnlimited()) { + amount = Math.min(shopHaveSpaces, invHaveItems); + amount = Math.min(amount, ownerCanAfford); + } else { + amount = Util.countItems(p.getInventory(), shop.getItem()); + // even if the shop is unlimited, the config option pay-unlimited-shop-owners is set to + // true, + // the unlimited shop owner should have enough money. + if (plugin.getConfig().getBoolean("shop.pay-unlimited-shop-owners")) { + amount = Math.min(amount, ownerCanAfford); + } + } + if (amount < 1) { // typed 'all' but the auto set amount is 0 + if (shopHaveSpaces == 0) { + // when typed 'all' but the shop doesn't have any empty space + MsgUtil.sendMessage(p, MsgUtil.getMessage("shop-has-no-space", p, "" + shopHaveSpaces, Util.getItemStackName(shop.getItem()))); + return; + } + if (ownerCanAfford == 0 && (!shop.isUnlimited() || plugin.getConfig().getBoolean("shop.pay-unlimited-shop-owners"))) { + // when typed 'all' but the shop owner doesn't have enough money to buy at least 1 + // item (and shop isn't unlimited or pay-unlimited is true) + MsgUtil.sendMessage(p, MsgUtil.getMessage("the-owner-cant-afford-to-buy-from-you", p, Objects.requireNonNull(format(shop.getPrice())), Objects.requireNonNull(format(ownerBalance)))); + return; + } + // when typed 'all' but player doesn't have any items to sell + MsgUtil.sendMessage(p, MsgUtil.getMessage("you-dont-have-that-many-items", p, "" + amount, Util.getItemStackName(shop.getItem()))); + return; + } + } else { + // instead of output cancelled message (when typed neither integer or 'all'), just let + // player know that there should be positive number or 'all' + MsgUtil.sendMessage(p, MsgUtil.getMessage("not-a-integer", p, message)); + Util.debugLog("Receive the chat " + message + " and it format failed: " + e.getMessage()); + return; + } + } + actionBuy(p, eco, actions, info, message, shop, amount); + } else if (shop.isSelling()) { + try { + amount = Integer.parseInt(message); + } catch (NumberFormatException e) { + int shopHaveItems = Util.countItems(((ContainerShop) shop).getInventory(), shop.getItem()); + int invHaveSpaces = Util.countSpace(p.getInventory(), shop.getItem()); + if (message.equalsIgnoreCase(plugin.getConfig().getString("shop.word-for-trade-all-items", "all"))) { + if (!shop.isUnlimited()) { + amount = Math.min(shopHaveItems, invHaveSpaces); + } else { + // should check not having items but having empty slots, cause player is trying to buy + // items from the shop. + amount = Util.countSpace(p.getInventory(), shop.getItem()); + } + // typed 'all', check if player has enough money than price * amount + double price = shop.getPrice(); + double balance = eco.getBalance(p.getUniqueId()); + amount = Math.min(amount, (int) Math.floor(balance / price)); + if (amount < 1) { // typed 'all' but the auto set amount is 0 + // when typed 'all' but player can't buy any items + if (!shop.isUnlimited() && shopHaveItems < 1) { + // but also the shop's stock is 0 + MsgUtil.sendMessage(p, MsgUtil.getMessage("shop-stock-too-low", p, "" + shop.getRemainingStock(), Util.getItemStackName(shop.getItem()))); + } else { + // when if player's inventory is full + if (invHaveSpaces == 0) { + MsgUtil.sendMessage(p, MsgUtil.getMessage("not-enough-space", p, String.valueOf(invHaveSpaces))); + return; + } + MsgUtil.sendMessage(p, MsgUtil.getMessage("you-cant-afford-to-buy", p, Objects.requireNonNull(format(price)), Objects.requireNonNull(format(balance)))); + } + return; + } + } else { + // instead of output cancelled message, just let player know that there should be positive + // number or 'all' + MsgUtil.sendMessage(p, MsgUtil.getMessage("not-a-integer", p, message)); + Util.debugLog("Receive the chat " + message + " and it format failed: " + e.getMessage()); + return; + } + } + actionSell(p, eco, actions, info, message, shop, amount); + } else { + MsgUtil.sendMessage(p, MsgUtil.getMessage("shop-purchase-cancelled", p)); + plugin.getLogger().warning("Shop data broken? Loc:" + shop.getLocation()); + } + } + + private @Nullable Shop getShopIncludeAttached_Fast(@NotNull Location loc, boolean fromAttach) { + return getShopIncludeAttached_Fast(loc, fromAttach, true); + } + + private @Nullable Shop getShopIncludeAttached_Fast(@NotNull Location loc, boolean fromAttach, boolean useCache) { + Shop shop; + //Try to get it directly + shop = getShop(loc); + + //failed, get attached shop + if (shop == null) { + Block currentBlock = loc.getBlock(); + if (!fromAttach) { + //sign + if (Util.isWallSign(currentBlock.getType())) { + Block attached = Util.getAttached(currentBlock); + if (attached != null) { + shop = this.getShopIncludeAttached_Fast(attached.getLocation(), true); + } + //double chest + } else { + @Nullable Block half = Util.getSecondHalf(currentBlock); + if (half != null) { + shop = getShop(half.getLocation()); + } + } + } + } + //add cache if using + if (plugin.getShopCache() != null && useCache) { + plugin.getShopCache().setCache(loc, shop); + } + + return shop; + } + + public class ShopIterator implements Iterator { + + private final Iterator>> worlds; + + private Iterator> chunks; + + private Iterator shops; + + public ShopIterator() { + //noinspection unchecked + HashMap>> worldsMap = (HashMap>>) getShops().clone(); + worlds = worldsMap.values().iterator(); + } + + /** + * Returns true if there is still more shops to iterate over. + */ + @Override + public boolean hasNext() { + if (shops == null || !shops.hasNext()) { + if (chunks == null || !chunks.hasNext()) { + if (!worlds.hasNext()) { + return false; + } else { + chunks = worlds.next().values().iterator(); + return hasNext(); + } + } else { + shops = chunks.next().values().iterator(); + return hasNext(); + } + } + return true; + } + + /** + * Fetches the next shop. Throws NoSuchElementException if there are no more shops. + */ + @Override + public @NotNull Shop next() { + if (shops == null || !shops.hasNext()) { + if (chunks == null || !chunks.hasNext()) { + if (!worlds.hasNext()) { + throw new NoSuchElementException("No more shops to iterate over!"); + } + chunks = worlds.next().values().iterator(); + } + shops = chunks.next().values().iterator(); + } + if (!shops.hasNext()) { + return this.next(); // Skip to the next one (Empty iterator?) + } + return shops.next(); + } + + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopModerator.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopModerator.java new file mode 100644 index 0000000..b0981bd --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopModerator.java @@ -0,0 +1,189 @@ +/* + * This file is a part of project QuickShop, the name is ShopModerator.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import java.util.ArrayList; +import java.util.UUID; +import lombok.EqualsAndHashCode; +import lombok.NonNull; +import org.jetbrains.annotations.NotNull; + +/** + * Contains shop's moderators infomations, owner, staffs etc. + */ +@EqualsAndHashCode +public class ShopModerator { + @NonNull + private UUID owner; + + @NonNull + private ArrayList staffs; + + private ShopModerator(@NotNull ShopModerator shopModerator) { + this.owner = shopModerator.owner; + this.staffs = shopModerator.staffs; + } + + /** + * Shop moderators, inlucding owner, and empty staffs. + * + * @param owner The owner + */ + public ShopModerator(@NotNull UUID owner) { + this.owner = owner; + this.staffs = new ArrayList<>(); + } + + /** + * Shop moderators, inlucding owner, staffs. + * + * @param owner The owner + * @param staffs The staffs + */ + public ShopModerator(@NotNull UUID owner, @NotNull ArrayList staffs) { + this.owner = owner; + this.staffs = staffs; + } + + public static ShopModerator deserialize(@NotNull String serilized) throws JsonSyntaxException { + // Use Gson deserialize data + Gson gson = new Gson(); + return gson.fromJson(serilized, ShopModerator.class); + } + + /** + * Add moderators staff to staff list + * + * @param player New staff + * @return Success + */ + public boolean addStaff(@NotNull UUID player) { + if (staffs.contains(player)) { + return false; + } + staffs.add(player); + return true; + } + + /** + * Remove all staffs + */ + public void clearStaffs() { + staffs.clear(); + } + + @Override + @SuppressWarnings("MethodDoesntCallSuperMethod") + public @NotNull ShopModerator clone() { + return new ShopModerator(this.owner, this.staffs); + } + + @Override + public @NotNull String toString() { + return serialize(this); + } + + public static String serialize(@NotNull ShopModerator shopModerator) { + Gson gson = new Gson(); + return gson.toJson(shopModerator); // Use Gson serialize this class + } + + /** + * Remove moderators staff from staff list + * + * @param player Staff + * @return Success + */ + public boolean delStaff(@NotNull UUID player) { + return staffs.remove(player); + } + + /** + * Get a player is or not moderators + * + * @param player Player + * @return yes or no, return true when it is staff or owner + */ + public boolean isModerator(@NotNull UUID player) { + if (isOwner(player)) { + return true; + } + return isStaff(player); + } + + /** + * Get a player is or not moderators owner + * + * @param player Player + * @return yes or no + */ + public boolean isOwner(@NotNull UUID player) { + return player.equals(owner); + } + + /** + * Get a player is or not moderators a staff + * + * @param player Player + * @return yes or no + */ + public boolean isStaff(@NotNull UUID player) { + return staffs.contains(player); + } + + /** + * Get moderators owner (Shop Owner). + * + * @return Owner's UUID + */ + public @NotNull UUID getOwner() { + return owner; + } + + /** + * Set moderators owner (Shop Owner) + * + * @param player Owner's UUID + */ + public void setOwner(@NotNull UUID player) { + this.owner = player; + } + + /** + * Get staffs list + * + * @return Staffs + */ + public @NotNull ArrayList getStaffs() { + return staffs; + } + + /** + * Set moderators staffs + * + * @param players staffs list + */ + public void setStaffs(@NotNull ArrayList players) { + this.staffs = players; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopProtectionFlag.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopProtectionFlag.java new file mode 100644 index 0000000..4593d78 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopProtectionFlag.java @@ -0,0 +1,47 @@ +/* + * This file is a part of project QuickShop, the name is ShopProtectionFlag.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@EqualsAndHashCode +@ToString +public class ShopProtectionFlag { + private String itemStackString; + + private String mark = "QuickShop DisplayItem"; + + private String shopLocation; + + public ShopProtectionFlag(String shopLocation, String itemStackString) { + this.shopLocation = shopLocation; + this.itemStackString = itemStackString; + } + + public static String getDefaultMark() { + return "QuickShop DisplayItem"; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopType.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopType.java new file mode 100644 index 0000000..e150d97 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/ShopType.java @@ -0,0 +1,51 @@ +/* + * This file is a part of project QuickShop, the name is ShopType.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.N; + +import org.jetbrains.annotations.NotNull; + +public enum ShopType { + // SELLING = SELLMODE BUYING = BUY MODE + SELLING(0), + BUYING(1); + + private final int id; + + ShopType(int id) { + this.id = id; + } + + public static @NotNull ShopType fromID(int id) { + for (ShopType type : ShopType.values()) { + if (type.id == id) { + return type; + } + } + return SELLING; + } + + public static int toID(@NotNull ShopType shopType) { + return shopType.id; + } + + public int toID() { + return id; + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/VirtualDisplayItem.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/VirtualDisplayItem.java new file mode 100644 index 0000000..8a00632 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/N/VirtualDisplayItem.java @@ -0,0 +1,377 @@ +/* + * This file is a part of project QuickShop, the name is VirtualDisplayItem.java + * Copyright (C) sandtechnology + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.abc.A.N; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.WrappedDataWatcher; +import java.lang.reflect.InvocationTargetException; +import java.util.*; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ConcurrentSkipListSet; +import java.util.concurrent.atomic.AtomicInteger; + +import org.abc.A.util.Util; +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class VirtualDisplayItem extends DisplayItem { + + + private static final ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager(); + + //counter for ensuring ID is unique + private static final AtomicInteger counter = new AtomicInteger(0); + + private static final String version = Util.getNMSVersion(); + + //unique EntityID + private final int entityID = counter.decrementAndGet(); + + //The List which store packet sender + private final Set packetSenders = new ConcurrentSkipListSet<>(); + + private final Queue asyncPacketSendQueue = new ConcurrentLinkedQueue<>(); + + private volatile boolean isDisplay; + + //packets + private PacketContainer fakeItemPacket; + + private PacketContainer fakeItemMetaPacket; + + private PacketContainer fakeItemVelocityPacket; + + private PacketContainer fakeItemDestroyPacket; + + //packetListener + private PacketAdapter packetAdapter; + + //cache chunk x and z + private ShopChunk chunkLocation; + + @Nullable + private BukkitTask asyncSendingTask; + + + public VirtualDisplayItem(@NotNull Shop shop) throws RuntimeException { + super(shop); + initFakeDropItemPacket(); + } + + private void initFakeDropItemPacket() { + + //First, create a new packet to spawn item + fakeItemPacket = protocolManager.createPacket(PacketType.Play.Server.SPAWN_ENTITY); + + //Location + Location location = getDisplayLocation(); + + //and add data based on packet class in NMS (global scope variable) + //Reference: https://wiki.vg/Protocol#Spawn_Object + fakeItemPacket.getIntegers() + //Entity ID + .write(0, entityID) + //Velocity x + .write(1, 0) + //Velocity y + .write(2, 0) + //Velocity z + .write(3, 0) + //Pitch + .write(4, 0) + //Yaw + .write(5, 0); + + switch (version) { + case "v1_13_R1": + case "v1_13_R2": + fakeItemPacket.getIntegers().write(6, 2); + //int data to mark + fakeItemPacket.getIntegers().write(7, 1); + break; + //int data to mark + default: + //for 1.14+, we should use EntityType + fakeItemPacket.getEntityTypeModifier().write(0, EntityType.DROPPED_ITEM); + //int data to mark + fakeItemPacket.getIntegers().write(6, 1); + } +// if (version == 13) { +// //for 1.13, we should use type id to represent the EntityType +// //2->minecraft:item (Object ID:https://wiki.vg/Object_Data) +// fakeItemPacket.getIntegers().write(6, 2); +// //int data to mark +// fakeItemPacket.getIntegers().write(7, 1); +// } else { +// //for 1.14+, we should use EntityType +// fakeItemPacket.getEntityTypeModifier().write(0, EntityType.DROPPED_ITEM); +// //int data to mark +// fakeItemPacket.getIntegers().write(6, 1); +// } + //UUID + fakeItemPacket.getUUIDs().write(0, UUID.randomUUID()); + //Location + fakeItemPacket.getDoubles() + //X + .write(0, location.getX()) + //Y + .write(1, location.getY()) + //Z + .write(2, location.getZ()); + + //Next, create a new packet to update item data (default is empty) + fakeItemMetaPacket = protocolManager.createPacket(PacketType.Play.Server.ENTITY_METADATA); + //Entity ID + fakeItemMetaPacket.getIntegers().write(0, entityID); + + //List Type are more complex + //Create a DataWatcher + WrappedDataWatcher wpw = new WrappedDataWatcher(); + //Must in the certain slot:https://wiki.vg/Entity_metadata#Item + //For 1.13 is 6, and 1.14+ is 7 + switch (version) { + case "v1_13_R1": + case "v1_13_R2": + wpw.setObject(6, WrappedDataWatcher.Registry.getItemStackSerializer(false), shop.getItem()); + break; + default: + wpw.setObject(7, WrappedDataWatcher.Registry.getItemStackSerializer(false), shop.getItem()); + break; + } +// wpw.setObject((version == 13 ? 6 : 7), WrappedDataWatcher.Registry.getItemStackSerializer(false), shop.getItem()); + //Add it + fakeItemMetaPacket.getWatchableCollectionModifier().write(0, wpw.getWatchableObjects()); + + //And, create a entity velocity packet to make it at a proper location (otherwise it will fly randomly) + fakeItemVelocityPacket = protocolManager.createPacket(PacketType.Play.Server.ENTITY_VELOCITY); + fakeItemVelocityPacket.getIntegers() + //Entity ID + .write(0, entityID) + //Velocity x + .write(1, 0) + //Velocity y + .write(2, 0) + //Velocity z + .write(3, 0); + + //Also make a DestroyPacket to remove it + fakeItemDestroyPacket = protocolManager.createPacket(PacketType.Play.Server.ENTITY_DESTROY); + //Entity to remove + fakeItemDestroyPacket.getIntegerArrays().write(0, new int[]{entityID}); + } + + @Override + public boolean checkDisplayIsMoved() { + return false; + } + + @Override + public boolean checkDisplayNeedRegen() { + return false; + } + + @Override + public boolean checkIsShopEntity(@NotNull Entity entity) { + return false; + } + + @Override + public void fixDisplayMoved() { + + } + + @Override + public void fixDisplayNeedRegen() { + + } + + @Override + public void remove() { + sendPacketToAll(fakeItemDestroyPacket); + unload(); + isDisplay = false; + } + + private void sendPacketToAll(@NotNull PacketContainer packet) { + Iterator iterator = packetSenders.iterator(); + while (iterator.hasNext()) { + Player nextPlayer = Bukkit.getPlayer(iterator.next()); + if (nextPlayer == null) { + iterator.remove(); + } else { + sendPacket(nextPlayer, packet); + } + } + } + + private void unload() { + packetSenders.clear(); + if(packetAdapter!=null) { + protocolManager.removePacketListener(packetAdapter); + } + if (asyncSendingTask != null && !asyncSendingTask.isCancelled()) { + asyncSendingTask.cancel(); + } + } + + private void sendPacket(@NotNull Player player, @NotNull PacketContainer packet) { + try { + protocolManager.sendServerPacket(player, packet); + } catch (InvocationTargetException e) { + throw new RuntimeException("An error occurred when sending a packet", e); + } + } + + @Override + public boolean removeDupe() { + return false; + } + + @Override + public void respawn() { + sendPacketToAll(fakeItemDestroyPacket); + sendFakeItemToAll(); + } + + public void sendFakeItemToAll() { + sendPacketToAll(fakeItemPacket); + sendPacketToAll(fakeItemMetaPacket); + sendPacketToAll(fakeItemVelocityPacket); + } + + @Override + public void safeGuard(@Nullable Entity entity) { + + } + + @Override + public void spawn() { + load(); + sendFakeItemToAll(); + isDisplay = true; + } + + //Due to the delay task in ChunkListener + //We must move load task to first spawn to prevent some bug and make the check lesser + private void load() { + //some time shop can be loaded when world isn't loaded + if (Util.isLoaded(shop.getLocation())) { + //Let nearby player can saw fake item + Collection entityCollection = shop.getLocation().getWorld().getNearbyEntities(shop.getLocation(), plugin.getServer().getViewDistance() * 16, shop.getLocation().getWorld().getMaxHeight(), plugin.getServer().getViewDistance() * 16); + for (Entity entity : entityCollection) { + if (entity instanceof Player) { + packetSenders.add(entity.getUniqueId()); + } + } + } + if (packetAdapter == null) { + packetAdapter = new PacketAdapter(plugin, ListenerPriority.HIGH, PacketType.Play.Server.MAP_CHUNK) { + @Override + public void onPacketSending(@NotNull PacketEvent event) { + //is really full chunk data + boolean isFull = event.getPacket().getBooleans().read(0); + if (!shop.isLoaded() || !isDisplay || !isFull || !Util.isLoaded(shop.getLocation())) { + return; + } + int x = event.getPacket().getIntegers().read(0); + //chunk z + int z = event.getPacket().getIntegers().read(1); + asyncPacketSendQueue.offer(() -> { + //chunk x + + //check later to prevent deadlock + if (chunkLocation == null) { + World world = shop.getLocation().getWorld(); + Chunk chunk = shop.getLocation().getChunk(); + chunkLocation = new ShopChunk(world.getName(), chunk.getX(), chunk.getZ()); + } + Player player = event.getPlayer(); + if (player == null || !player.isOnline()) { + Util.debugLog("Cancelled packet sending cause player logged out when sending packets."); + return; + } + if (chunkLocation.isSame(player.getWorld().getName(), x, z)) { + packetSenders.add(player.getUniqueId()); + sendFakeItem(player); + } + }); +// Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> { +// if (chunkLocation == null) { +// World world = shop.getLocation().getWorld(); +// Chunk chunk = shop.getLocation().getChunk(); +// chunkLocation = new ShopChunk(world.getName(), chunk.getX(), chunk.getZ()); +// } +// if (chunkLocation.isSame(event.getPlayer().getWorld().getName(), x, z)) { +// packetSenders.add(event.getPlayer().getUniqueId()); +// sendFakeItem(event.getPlayer()); +// } +// }, 1); + } + }; + } + protocolManager.addPacketListener(packetAdapter); + asyncSendingTask = new BukkitRunnable() { + @Override + public void run() { + Runnable runnable = asyncPacketSendQueue.poll(); + while (runnable != null) { + runnable.run(); + runnable = asyncPacketSendQueue.poll(); + } + } + }.runTaskTimerAsynchronously(plugin, 0, 1); + } + + public void sendFakeItem(@NotNull Player player) { + sendPacket(player, fakeItemPacket); + sendPacket(player, fakeItemMetaPacket); + sendPacket(player, fakeItemVelocityPacket); + } + + @Override + public @Nullable Entity getDisplay() { + return null; + } + + @Override + public @NotNull Location getDisplayLocation() { + return shop.getLocation().clone().add(0.5, 1.2, 0.5); + } + + @Override + public boolean isSpawned() { + return isDisplay; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/DisplayAutoDespawnWatcher.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/DisplayAutoDespawnWatcher.java new file mode 100644 index 0000000..0135246 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/DisplayAutoDespawnWatcher.java @@ -0,0 +1,79 @@ +/* + * This file is a part of project QuickShop, the name is DisplayAutoDespawnWatcher.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.O; + +import lombok.AllArgsConstructor; +import org.abc.A.N.Shop; +import org.abc.A.util.Util; +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitRunnable; +import org.abc.A.QuickShop; + +@AllArgsConstructor +public class DisplayAutoDespawnWatcher extends BukkitRunnable { + private QuickShop plugin; + + @Override + public void run() { + int range = plugin.getConfig().getInt("shop.display-despawn-range"); + + plugin + .getShopManager() + .getLoadedShops() + .stream() + .filter(shop -> shop.getDisplay() != null) + .forEach( + shop -> { + // Check the range has player? + boolean anyPlayerInRegion = + Bukkit.getOnlinePlayers().stream() + .filter(player -> player.getWorld() == shop.getLocation().getWorld()) + .anyMatch( + player -> player.getLocation().distance(shop.getLocation()) < range); + + if (anyPlayerInRegion) { + if (!shop.getDisplay().isSpawned()) { + Util.debugLog( + "Respawning the shop " + + shop + + " the display, cause it was despawned and a player close it"); + Bukkit.getScheduler().runTask(plugin, shop::checkDisplay); + } + } else if (shop.getDisplay().isSpawned()) { + removeDisplayItemDelayed(shop); + } + }); + } + + public boolean removeDisplayItemDelayed(Shop shop) { + if (shop.getDisplay().isPendingRemoval()) { + // Actually remove the pending display + Util.debugLog("Removing the shop " + shop + " the display, cause nobody can see it"); + Bukkit.getScheduler().runTask(plugin, () -> shop.getDisplay().remove()); + return true; + } else { + // Delayed to next calling + Util.debugLog("Pending to remove the shop " + shop + " the display, cause nobody can see it"); + shop.getDisplay().pendingRemoval(); + return false; + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/DisplayDupeRemoverWatcher.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/DisplayDupeRemoverWatcher.java new file mode 100644 index 0000000..7f87771 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/DisplayDupeRemoverWatcher.java @@ -0,0 +1,43 @@ +/* + * This file is a part of project QuickShop, the name is DisplayDupeRemoverWatcher.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.O; + +import org.abc.A.N.DisplayItem; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; + +import java.util.LinkedList; +import java.util.Queue; + +public class DisplayDupeRemoverWatcher extends BukkitRunnable { + private final Queue checkQueue = new LinkedList<>(); + + @Override + public + void run() { + checkQueue.forEach(DisplayItem::removeDupe); + } + + public + void add(@NotNull DisplayItem displayItem) { + checkQueue.offer(displayItem); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/DisplayWatcher.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/DisplayWatcher.java new file mode 100644 index 0000000..045deaa --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/DisplayWatcher.java @@ -0,0 +1,58 @@ +/* + * This file is a part of project QuickShop, the name is DisplayWatcher.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.O; + +import lombok.Data; +import org.abc.A.N.DisplayItem; +import org.bukkit.scheduler.BukkitRunnable; +import org.abc.A.QuickShop; +import org.abc.A.N.DisplayType; +import org.abc.A.N.Shop; + +@Data +public class DisplayWatcher { + private QuickShop plugin; + + public DisplayWatcher(QuickShop plugin) { + this.plugin = plugin; + registerTask(); + } + + private void registerTask() { + plugin.getLogger().info("Registering DisplayCheck task...."); + if (DisplayItem.getNowUsing() == DisplayType.VIRTUALITEM) { + return; + } + if (plugin.isDisplay() && plugin.getDisplayItemCheckTicks() > 0) { + new BukkitRunnable() { + @Override + public void run() { + if (plugin.getConfig().getInt("shop.display-items-check-ticks") < 3000) { + plugin.getLogger().severe("Shop.display-items-check-ticks is too low! It may cause HUGE lag! Pick a number > 3000"); + } + for (Shop shop : plugin.getShopManager().getLoadedShops()) { + shop.checkDisplay(); + } + } + }.runTaskTimer(plugin, 1L, plugin.getDisplayItemCheckTicks()); + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/InventoryEditContainer.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/InventoryEditContainer.java new file mode 100644 index 0000000..22c00a6 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/InventoryEditContainer.java @@ -0,0 +1,38 @@ +/* + * This file is a part of project QuickShop, the name is InventoryEditContainer.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.O; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +@Data +@Builder +@AllArgsConstructor +public class InventoryEditContainer { + private Inventory inventory; + + private int slot; + + private ItemStack newItemStack; + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/LogWatcher.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/LogWatcher.java new file mode 100644 index 0000000..438abf7 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/LogWatcher.java @@ -0,0 +1,100 @@ +/* + * This file is a part of project QuickShop, the name is LogWatcher.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.O; + +import java.io.*; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Date; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import lombok.NonNull; +import lombok.SneakyThrows; +import org.abc.A.util.Util; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; +import org.abc.A.QuickShop; + +public class LogWatcher extends BukkitRunnable { + private final Queue logs = new ConcurrentLinkedQueue<>(); + + private FileWriter logFileWriter = null; + + private PrintWriter pw; + + public LogWatcher(QuickShop plugin, File log) { + try { + if (!log.exists()) { + log.createNewFile(); + } + logFileWriter = new FileWriter(log, true); + pw = new PrintWriter(logFileWriter); + } catch (FileNotFoundException e) { + e.printStackTrace(); + plugin.getLogger().severe("Log file was not found!"); + } catch (IOException e) { + e.printStackTrace(); + plugin.getLogger().severe("Could not create the log file!"); + } + } + + @SneakyThrows + public void close() { + if (logFileWriter != null) { + logFileWriter.flush(); + logFileWriter.close(); + } + } + + public void log(@NonNull String log) { + Date date = Calendar.getInstance().getTime(); + Timestamp time = new Timestamp(date.getTime()); + this.add("[" + time + "] " + log); + } + + public void add(@NotNull String s) { + logs.add(s); + } + + @Override + public void run() { + for (String log : logs) { + if (logFileWriter == null) { + continue; + } + if (pw == null) { + continue; + } + pw.println(log); + } + logs.clear(); + if (logFileWriter != null) { + try { + if (pw != null) { + pw.flush(); + } + logFileWriter.flush(); + } catch (IOException ioe) { + Util.debugLog("Failed to flush log to disk: " + ioe.getMessage()); + } + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/OngoingFeeWatcher.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/OngoingFeeWatcher.java new file mode 100644 index 0000000..ca01f4b --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/OngoingFeeWatcher.java @@ -0,0 +1,106 @@ +/* + * This file is a part of project QuickShop, the name is OngoingFeeWatcher.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.O; + +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; +import org.abc.A.QuickShop; +import org.abc.A.N.Shop; + +import java.util.Objects; +import java.util.UUID; + +/** + * Check the shops after server booted up, make sure shop can correct self-deleted when container + * lost. + */ +public class OngoingFeeWatcher extends BukkitRunnable { + private final QuickShop plugin; + + public OngoingFeeWatcher(@NotNull QuickShop plugin) { + this.plugin = plugin; + } + + @Override + public void run() { + Util.debugLog("Run task for ongoing fee..."); + if (plugin.getEconomy() == null) { + Util.debugLog("Economy hadn't get ready."); + return; + } + int cost = plugin.getConfig().getInt("shop.ongoing-fee.cost-per-shop"); + boolean allowLoan = plugin.getConfig().getBoolean("shop.allow-economy-loan"); + boolean ignoreUnlimited = plugin.getConfig().getBoolean("shop.ongoing-fee.ignore-unlimited"); + for (Shop shop : plugin.getShopManager().getAllShops()) { + if (!shop.isUnlimited() || !ignoreUnlimited) { + UUID shopOwner = shop.getOwner(); + Bukkit.getScheduler().runTask(plugin, () -> { + if (!allowLoan) { + // Disallow loan + if (plugin.getEconomy().getBalance(shopOwner) < cost) { + this.removeShop(shop); + } + } + boolean success = plugin.getEconomy().withdraw(shop.getOwner(), cost); + if (!success) { + this.removeShop(shop); + } else { + try { + //noinspection ConstantConditions,deprecation + plugin.getEconomy().deposit(Bukkit.getOfflinePlayer(plugin.getConfig().getString("tax")).getUniqueId(), cost); + } catch (Exception ignored) { + } + } + }); + } else { + Util.debugLog( + "Shop was ignored for ongoing fee cause it is unlimited and ignoreUnlimited = true : " + + shop); + } + } + } + + /** + * Remove shop and send alert to shop owner + * + * @param shop The shop was remove cause no enough ongoing fee + */ + public void removeShop(@NotNull Shop shop) { + Bukkit.getScheduler().runTask(plugin, (@NotNull Runnable) shop::delete); + MsgUtil.send( + shop.getOwner(), + MsgUtil.getMessageOfflinePlayer( + "shop-removed-cause-ongoing-fee", + Bukkit.getOfflinePlayer(shop.getOwner()), + "World:" + + Objects.requireNonNull(shop.getLocation().getWorld()).getName() + + " X:" + + shop.getLocation().getBlockX() + + " Y:" + + shop.getLocation().getBlockY() + + " Z:" + + shop.getLocation().getBlockZ()), + shop.isUnlimited()); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/ShopContainerWatcher.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/ShopContainerWatcher.java new file mode 100644 index 0000000..a67cb8f --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/ShopContainerWatcher.java @@ -0,0 +1,57 @@ +/* + * This file is a part of project QuickShop, the name is ShopContainerWatcher.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.O; + +import org.abc.A.N.ContainerShop; +import org.abc.A.N.Shop; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Check the shops after server booted up, make sure shop can correct self-deleted when container + * lost. + */ +public class ShopContainerWatcher extends BukkitRunnable { + private final Queue checkQueue = new LinkedList<>(); + + public void scheduleCheck(@NotNull Shop shop) { + checkQueue.add(shop); + } + + @Override + public void run() { + long beginTime = System.currentTimeMillis(); + Shop shop = checkQueue.poll(); + while (shop != null) { + if (shop instanceof ContainerShop) { + ((ContainerShop) shop).checkContainer(); + } + if (System.currentTimeMillis() - beginTime + > 45) { // Don't let quickshop eat more than 45 ms per tick. + break; + } + shop = checkQueue.poll(); + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/SignUpdateWatcher.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/SignUpdateWatcher.java new file mode 100644 index 0000000..6d1fca4 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/SignUpdateWatcher.java @@ -0,0 +1,48 @@ +/* + * This file is a part of project QuickShop, the name is SignUpdateWatcher.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.O; + +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; +import org.abc.A.N.Shop; + +import java.util.LinkedList; +import java.util.Queue; + +public class SignUpdateWatcher extends BukkitRunnable { + private final Queue signUpdateQueue = new LinkedList<>(); + + public void scheduleSignUpdate(@NotNull Shop shop) { + if (signUpdateQueue.contains(shop)) { + return; // Ignore + } + signUpdateQueue.add(shop); + } + + @Override + public void run() { + Shop shop = signUpdateQueue.poll(); + while (shop != null) { + shop.setSignText(); + shop = signUpdateQueue.poll(); + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/SyncTaskWatcher.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/SyncTaskWatcher.java new file mode 100644 index 0000000..46dc842 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/SyncTaskWatcher.java @@ -0,0 +1,92 @@ +/* + * This file is a part of project QuickShop, the name is SyncTaskWatcher.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.O; + +import java.util.LinkedList; +import java.util.Queue; +import lombok.Getter; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; +import org.abc.A.QuickShop; + +public class SyncTaskWatcher { + @Getter + private Queue entityRemoveQueue = new LinkedList<>(); + + @Getter + private Queue inventoryEditQueue = new LinkedList<>(); + + @Getter + private Queue itemStackRemoveQueue = new LinkedList<>(); + // private QuickShop plugin; + + /** + * SyncTaskWatcher is a loop task runner, it can be add from async thread and run in Bukkit main + * thread. + * + * @param plugin QuickShop instance + */ + public SyncTaskWatcher(QuickShop plugin) { + // this.plugin = plugin; + new BukkitRunnable() { + @Override + public void run() { + if (entityRemoveQueue.isEmpty()) { + return; + } + Entity entity = entityRemoveQueue.poll(); + while (entity != null) { + entity.remove(); + entity = entityRemoveQueue.poll(); + } + } + }.runTaskTimer(plugin, 0, 5); + new BukkitRunnable() { + @Override + public void run() { + if (itemStackRemoveQueue.isEmpty()) { + return; + } + ItemStack itemStack = itemStackRemoveQueue.poll(); + while (itemStack != null) { + itemStack.setAmount(0); + itemStack.setType(Material.AIR); + itemStack = itemStackRemoveQueue.poll(); + } + } + }.runTaskTimer(plugin, 0, 5); + new BukkitRunnable() { + @Override + public void run() { + if (inventoryEditQueue.isEmpty()) { + return; + } + InventoryEditContainer container = inventoryEditQueue.poll(); + while (container != null) { + container.getInventory().setItem(container.getSlot(), container.getNewItemStack()); + container = inventoryEditQueue.poll(); + } + } + }.runTaskTimer(plugin, 0, 5); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/UpdateWatcher.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/UpdateWatcher.java new file mode 100644 index 0000000..2ab73cd --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/O/UpdateWatcher.java @@ -0,0 +1,198 @@ +/* + * This file is a part of project QuickShop, the name is UpdateWatcher.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.O; + +import java.util.List; +import java.util.Random; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.TextComponent; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.UpdateInfomation; +import org.abc.A.util.Updater; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; +import org.jetbrains.annotations.NotNull; +import org.abc.A.QuickShop; + +public class UpdateWatcher implements Listener { + public static boolean hasNewUpdate = false; + + private static BukkitTask cronTask = null; + + private static UpdateInfomation info = null; + + public static String fixVer(@NotNull String originalVer) { + originalVer = originalVer.replaceAll(QuickShop.getFork(), ""); + originalVer = originalVer.trim(); + return originalVer; + } + + public static void init() { + cronTask = + new BukkitRunnable() { + + @Override + public void run() { + info = Updater.checkUpdate(); + + if (info.getVersion() == null) { + hasNewUpdate = false; + return; + } + + if (info.getVersion().equals(QuickShop.getVersion())) { + hasNewUpdate = false; + return; + } + hasNewUpdate = true; + + if (!info.isBeta()) { + QuickShop.instance + .getLogger() + .info( + "A new version of QuickShop has been released! [" + info.getVersion() + "]"); + QuickShop.instance + .getLogger() + .info("Update here: https://www.spigotmc.org/resources/62575/"); + + Bukkit.getOnlinePlayers() + .forEach( + player -> { + if (QuickShop.getPermissionManager() + .hasPermission(player, "quickshop.alert")) { + List notifys = + MsgUtil.getI18nFile().getStringList("updatenotify.list"); + Random random = new Random(); + int notifyNum = -1; + if (notifys.size() > 1) { + notifyNum = random.nextInt(notifys.size()); + } + String notify; + if (notifyNum > 0) { // Translate bug. + notify = notifys.get(notifyNum); + } else { + notify = "New update {0} now avaliable! Please update!"; + } + notify = + MsgUtil.fillArgs(notify, info.getVersion(), QuickShop.getVersion()); + TextComponent updatenow = + new TextComponent( + ChatColor.AQUA + + MsgUtil.getMessage("updatenotify.buttontitle", player)); + TextComponent onekeyupdate = + new TextComponent( + ChatColor.YELLOW + + MsgUtil.getMessage( + "updatenotify.onekeybuttontitle", player)); + updatenow.setClickEvent( + new ClickEvent( + ClickEvent.Action.OPEN_URL, + "https://www.spigotmc.org/resources/62575/")); + onekeyupdate.setClickEvent( + new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/qs update")); + TextComponent finallyText = + new TextComponent(updatenow, new TextComponent(" "), onekeyupdate); + player.sendMessage( + ChatColor.GREEN + + "---------------------------------------------------"); + player.sendMessage(ChatColor.GREEN + notify); + player.spigot().sendMessage(finallyText); + player.sendMessage( + ChatColor.GREEN + + "---------------------------------------------------"); + } + }); + } else { + QuickShop.instance.getLogger().info("A new BETA version of QuickShop is available!"); + QuickShop.instance + .getLogger() + .info("Update here: https://www.spigotmc.org/resources/62575/"); + QuickShop.instance + .getLogger() + .info("This is a BETA version, which means you should use it with caution."); + } + } + }.runTaskTimerAsynchronously(QuickShop.instance, 1, 20 * 60 * 60); + } + + public static void uninit() { + hasNewUpdate = false; + if (cronTask == null) { + return; + } + cronTask.cancel(); + } + + @EventHandler + public void playerJoin(PlayerJoinEvent e) { + if (!hasNewUpdate + || !QuickShop.getPermissionManager().hasPermission(e.getPlayer(), "quickshop.alert")) { + return; + } + new BukkitRunnable() { + @Override + public void run() { + if (!info.isBeta()) { + List notifys = MsgUtil.getI18nFile().getStringList("updatenotify.list"); + Random random = new Random(); + int notifyNum = random.nextInt(notifys.size()); + String notify = notifys.get(notifyNum); + notify = MsgUtil.fillArgs(notify, info.getVersion(), QuickShop.getVersion()); + + TextComponent updatenow = + new TextComponent( + ChatColor.AQUA + MsgUtil.getMessage("updatenotify.buttontitle", e.getPlayer())); + TextComponent onekeyupdate = + new TextComponent( + ChatColor.YELLOW + + MsgUtil.getMessage("updatenotify.onekeybuttontitle", e.getPlayer())); + updatenow.setClickEvent( + new ClickEvent( + ClickEvent.Action.OPEN_URL, "https://www.spigotmc.org/resources/62575/")); + onekeyupdate.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/qs update")); + TextComponent finallyText = + new TextComponent(updatenow, new TextComponent(" "), onekeyupdate); + e.getPlayer() + .sendMessage(ChatColor.GREEN + "---------------------------------------------------"); + e.getPlayer().sendMessage(ChatColor.GREEN + notify); + e.getPlayer().spigot().sendMessage(finallyText); + e.getPlayer() + .sendMessage(ChatColor.GREEN + "---------------------------------------------------"); + } else { + e.getPlayer() + .sendMessage(ChatColor.GRAY + "A new BETA version of QuickShop has been released!"); + e.getPlayer() + .sendMessage( + ChatColor.GRAY + "Update here: https://www.spigotmc.org/resources/62575/"); + e.getPlayer() + .sendMessage( + ChatColor.GRAY + + "This is a BETA version, which means you should use it with caution."); + } + } + }.runTaskLater(QuickShop.instance, 80); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/QuickShop.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/QuickShop.java new file mode 100644 index 0000000..c92a81e --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/QuickShop.java @@ -0,0 +1,1518 @@ +/* + * This file is a part of project QuickShop, the name is QuickShop.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A; + +import lombok.Getter; +import lombok.Setter; +import me.minebuilders.clearlag.Clearlag; +import me.minebuilders.clearlag.listeners.ItemMergeListener; +import org.abc.A.B.QuickShopAPI; +import org.abc.A.E.*; +import org.abc.A.F.*; +import org.abc.A.I.IntegrateStage; +import org.abc.A.I.Towny.TownyIntegration; +import org.abc.A.J.*; +import org.abc.A.M.PermissionManager; +import org.abc.A.N.*; +import org.abc.A.util.*; +import org.abc.A.util.Timer; +import org.abc.A.O.*; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.RegisteredListener; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.C.InternalListener; +import org.abc.A.D.CommandManager; +import org.abc.A.I.FactionsUUID.FactionsUUIDIntegration; +import org.abc.A.I.PlotSquared.PlotSquaredIntegration; +import org.abc.A.I.Residence.ResidenceIntegration; +import org.abc.A.I.WorldGuard.WorldGuardIntegration; +import org.abc.A.util.bukkitwrapper.BukkitAPIWrapper; +import org.abc.A.util.bukkitwrapper.SpigotWrapper; +import org.abc.A.util.compatibility.CompatibilityManager; +import org.abc.A.util.matcher.item.BukkitItemMatcherImpl; +import org.abc.A.util.matcher.item.ItemMatcher; +import org.abc.A.util.matcher.item.QuickShopItemMatcherImpl; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.*; +import java.util.Map.Entry; + + +public class QuickShop extends JavaPlugin { + + /** + * The active instance of QuickShop + */ + @Getter + public static QuickShop instance; + + /** + * The manager to check permissions. + */ + private static PermissionManager permissionManager; + + @Getter + private IntegrationHelper integrationHelper; + + // Listeners (These don't) + private BlockListener blockListener; + + /** + * The BootError, if it not NULL, plugin will stop loading and show setted errors when use /qs + */ + @Nullable + @Getter + @Setter + private BootError bootError; + + // Listeners - We decide which one to use at runtime + private ChatListener chatListener; + + private ChunkListener chunkListener; + + @Getter + private CommandManager commandManager; + + /** + * WIP + */ + @Getter + private CompatibilityManager compatibilityTool = new CompatibilityManager(); + + private CustomInventoryListener customInventoryListener; + + /** + * The database for storing all our data for persistence + */ + @Getter + private Database database; + + /** + * Contains all SQL tasks + */ + @Getter + private DatabaseHelper databaseHelper; + + /** + * Queued database manager + */ + @Getter + private DatabaseManager databaseManager; + + /** + * Default database prefix, can overwrite by config + */ + @Getter + private String dbPrefix = ""; + + /** + * Whether we should use display items or not + */ + @Getter + private boolean display = true; + + private DisplayBugFixListener displayBugFixListener; + + @Getter + private int displayItemCheckTicks; + + @Getter + private DisplayWatcher displayWatcher; + + /** + * The economy we hook into for transactions + */ + @Getter + private Economy economy; + + private DisplayProtectionListener inventoryListener; + + @Getter + private ItemMatcher itemMatcher; + + /** + * Language manager, to select which language will loaded. + */ + @Getter + private Language language; + + /** + * Whether or not to limit players shop amounts + */ + @Getter + private boolean limit = false; + + /** + * The shop limites. + */ + @Getter + private HashMap limits = new HashMap<>(); + + private LockListener lockListener; + + // private BukkitTask itemWatcherTask; + @Nullable + @Getter + private LogWatcher logWatcher; + + /** + * bStats, good helper for metrics. + */ + private Metrics metrics; + + /** + * The plugin OpenInv (null if not present) + */ + @Getter + private Plugin openInvPlugin; + + /** + * The plugin PlaceHolderAPI(null if not present) + */ + @Getter + private Plugin placeHolderAPI; + + /** + * A util to call to check some actions permission + */ + @Getter + private PermissionChecker permissionChecker; + + private PlayerListener playerListener; + + private InternalListener internalListener; + + /** + * Whether we players are charged a fee to change the price on their shop (To help deter endless + * undercutting + */ + @Getter + private boolean priceChangeRequiresFee = false; + + /** + * The error reporter to help devs report errors to Sentry.io + */ + @Getter + private SentryErrorReporter sentryErrorReporter; + + /** + * The server UniqueID, use to the ErrorReporter + */ + @Getter + private UUID serverUniqueID; + + private boolean setupDBonEnableding = false; + + /** + * Rewrited shoploader, more faster. + */ + @Getter + private ShopLoader shopLoader; + + /** + * The Shop Manager used to store shops + */ + @Getter + private ShopManager shopManager; + + private ShopProtectionListener shopProtectListener; + + @Getter + private SyncTaskWatcher syncTaskWatcher; + + // private ShopVaildWatcher shopVaildWatcher; + @Getter + private DisplayAutoDespawnWatcher displayAutoDespawnWatcher; + + private WorldListener worldListener; + + @Getter + private OngoingFeeWatcher ongoingFeeWatcher; + + @Getter + private SignUpdateWatcher signUpdateWatcher; + + @Getter + private ShopContainerWatcher shopContainerWatcher; + + @Getter + private @Deprecated + DisplayDupeRemoverWatcher displayDupeRemoverWatcher; + + @Getter + private BukkitAPIWrapper bukkitAPIWrapper; + + @Getter + private boolean enabledAsyncDisplayDespawn; + + @Getter + private String previewProtectionLore; + + @Getter + private Plugin blockHubPlugin; + + @Getter + private Cache shopCache; + + /** + * Returns QS version, this method only exist on QSRR forks If running other QSRR forks,, result + * may not is "Reremake x.x.x" If running QS offical, Will throw exception. + * + * @return Plugin Version + */ + public static String getVersion() { + return QuickShop.instance.getDescription().getVersion(); + } + + /** + * Get the Player's Shop limit. + * + * @param p The player you want get limit. + * @return int Player's shop limit + */ + public int getShopLimit(@NotNull Player p) { + int max = getConfig().getInt("limits.default"); + for (Entry entry : limits.entrySet()) { + if (entry.getValue() > max && getPermissionManager().hasPermission(p, entry.getKey())) { + max = entry.getValue(); + } + } + return max; + } + + /** + * Get the permissionManager as static + * + * @return the permission Manager. + */ + public static PermissionManager getPermissionManager() { + return permissionManager; + } + + /** + * Load 3rdParty plugin support module. + */ + private void load3rdParty() { + // added for compatibility reasons with OpenInv - see + // https://github.com/KaiKikuchi/QuickShop/issues/139 + if (getConfig().getBoolean("plugin.OpenInv")) { + this.openInvPlugin = Bukkit.getPluginManager().getPlugin("OpenInv"); + if (this.openInvPlugin != null) { + getLogger().info("Successfully loaded OpenInv support!"); + } + } + if (getConfig().getBoolean("plugin.PlaceHolderAPI")) { + this.placeHolderAPI = Bukkit.getPluginManager().getPlugin("PlaceholderAPI"); + if (this.placeHolderAPI != null) { + getLogger().info("Successfully loaded PlaceHolderAPI support!"); + } + } + if (getConfig().getBoolean("plugin.BlockHub")) { + this.blockHubPlugin = Bukkit.getPluginManager().getPlugin("BlockHub"); + if (this.blockHubPlugin != null) { + getLogger().info("Successfully loaded BlockHub support!"); + } + } + if (this.display) { + //VirtualItem support + if (DisplayItem.getNowUsing() == DisplayType.VIRTUALITEM) { + getLogger().info("Using Virtual item Display, loading ProtocolLib support..."); + Plugin protocolLibPlugin = Bukkit.getPluginManager().getPlugin("ProtocolLib"); + if (protocolLibPlugin != null && protocolLibPlugin.isEnabled()) { + getLogger().info("Successfully loaded ProtocolLib support!"); + } else { + getLogger().warning("Failed to load ProtocolLib support, fallback to real item display"); + getConfig().set("shop.display-type", 0); + saveConfig(); + } + } + + if (DisplayItem.getNowUsing() != DisplayType.VIRTUALITEM && Bukkit.getPluginManager().getPlugin("ClearLag") != null) { + try { + Clearlag clearlag = (Clearlag) Bukkit.getPluginManager().getPlugin("ClearLag"); + for (RegisteredListener clearLagListener : ItemSpawnEvent.getHandlerList().getRegisteredListeners()) { + if (!clearLagListener.getPlugin().equals(clearlag)) { + continue; + } + int spamTimes = 20; + if (clearLagListener.getListener().getClass().equals(ItemMergeListener.class)) { + ItemSpawnEvent.getHandlerList().unregister(clearLagListener.getListener()); + for (int i = 0; i < spamTimes; i++) { + getLogger().warning("+++++++++++++++++++++++++++++++++++++++++++"); + getLogger().severe("Detected incompatible module of ClearLag-ItemMerge module, it will broken the QuickShop display, we already unregister this module listener!"); + getLogger().severe("Please turn off it in the ClearLag config.yml or turn off the QuickShop display feature!"); + getLogger().severe("If you didn't do that, this message will keep spam in your console every times you server boot up!"); + getLogger().warning("+++++++++++++++++++++++++++++++++++++++++++"); + getLogger().info("This message will spam more " + (spamTimes - i) + " times!"); + } + } + } + } catch (Throwable ignored) { + } + } + } + } + + /** + * Tries to load the economy and its core. If this fails, it will try to use vault. If that fails, + * it will return false. + * + * @return true if successful, false if the core is invalid or is not found, and vault cannot be + * used. + */ + private boolean loadEcon() { + try { + // EconomyCore core = new Economy_Vault(); + EconomyCore core = null; + switch (EconomyType.fromID(getConfig().getInt("economy-type"))) { + case UNKNOWN: + bootError = new BootError("Can't load the Economy provider, invaild value in config.yml."); + return false; + case VAULT: + core = new Economy_Vault(); + Util.debugLog("Now using the Vault economy system."); + break; + case RESERVE: + core = new Economy_Reserve(); + Util.debugLog("Now using the Reserve economy system."); + break; + default: + Util.debugLog("No any economy provider selected."); + break; + } + if (core == null) { + return false; + } + if (!core.isValid()) { + // getLogger().severe("Economy is not valid!"); + bootError = BuiltInSolution.econError(); + // if(econ.equals("Vault")) + // getLogger().severe("(Does Vault have an Economy to hook into?!)"); + return false; + } else { + this.economy = new Economy(ServiceInjector.getEconomyCore(core)); + return true; + } + } catch (Exception e) { + this.getSentryErrorReporter().ignoreThrow(); + e.printStackTrace(); + getLogger().severe("QuickShop could not hook into a economy/Not found Vault or Reserve!"); + getLogger().severe("QuickShop CANNOT start!"); + bootError = BuiltInSolution.econError(); + HandlerList.unregisterAll(this); + getLogger().severe("Plugin listeners was disabled, please fix the economy issue."); + return false; + } + } + + /** + * Logs the given string to qs.log, if QuickShop is configured to do so. + * + * @param s The string to log. It will be prefixed with the date and time. + */ + public void log(@NotNull String s) { + if (this.getLogWatcher() == null) { + return; + } + this.getLogWatcher().log(s); + } + + /** + * Reloads QuickShops config + */ + @Override + public void reloadConfig() { + super.reloadConfig(); + // Load quick variables + this.display = this.getConfig().getBoolean("shop.display-items"); + this.priceChangeRequiresFee = this.getConfig().getBoolean("shop.price-change-requires-fee"); + this.displayItemCheckTicks = this.getConfig().getInt("shop.display-items-check-ticks"); + language = new Language(this); // Init locale + if (this.getConfig().getBoolean("log-actions")) { + logWatcher = new LogWatcher(this, new File(getDataFolder(), "qs.log")); + } else { + logWatcher = null; + } + } + + /** + * Early than onEnable, make sure instance was loaded in first time. + */ + @Override + public void onLoad() { + instance = this; + QuickShopAPI.setupApi(this); + getDataFolder().mkdirs(); +// replaceLogger(); + + this.bootError = null; + getLogger().info("Loading up integration modules."); + this.integrationHelper = new IntegrationHelper(); + this.integrationHelper.callIntegrationsLoad(IntegrateStage.onLoadBegin); + if (getConfig().getBoolean("integration.worldguard.enable")) { + Plugin wg = Bukkit.getPluginManager().getPlugin("WorldGuard"); + Util.debugLog("Check WG plugin..."); + if (wg != null) { + Util.debugLog("Loading WG modules."); + this.integrationHelper.register(new WorldGuardIntegration(this)); // WG require register flags when onLoad called. + } + } + + this.integrationHelper.callIntegrationsLoad(IntegrateStage.onLoadAfter); + } + + @Override + public void onDisable() { + this.integrationHelper.callIntegrationsUnload(IntegrateStage.onUnloadBegin); + getLogger().info("QuickShop is finishing remaining work, this may need a while..."); +// if (sentryErrorReporter != null && sentryErrorReporter.isEnabled()) { +// Paste paste = new Paste(this); +// String lastPaste = paste.paste(paste.genNewPaste(), 1); +// if (lastPaste != null) { +// log("Plugin unloaded, the server paste was created for debugging, reporting errors and data-recovery: " + lastPaste); +// } +// } + Util.debugLog("Closing all GUIs..."); + for (Player player : Bukkit.getOnlinePlayers()) { + player.closeInventory(); + } + Util.debugLog("Unloading all shops..."); + try { + Objects.requireNonNull(this.getShopManager().getLoadedShops()).forEach(Shop::onUnload); + } catch (Throwable th) { + // ignore, we didn't care that + } + + Util.debugLog("Cleaning up database queues..."); + if (this.getDatabaseManager() != null) { + this.getDatabaseManager().unInit(); + } + + Util.debugLog("Unregistering tasks..."); + // if (itemWatcherTask != null) + // itemWatcherTask.cancel(); + if (logWatcher != null) { + logWatcher.close(); // Closes the file + } + /* Unload UpdateWatcher */ + UpdateWatcher.uninit(); + Util.debugLog("Cleaning up resources and unloading all shops..."); + /* Remove all display items, and any dupes we can find */ + if (shopManager != null) { + shopManager.clear(); + } + /* Close Database */ + if (database != null) { + this.database.close(); + } + // this.reloadConfig(); + Util.debugLog("Calling integrations..."); + this.integrationHelper.callIntegrationsLoad(IntegrateStage.onUnloadAfter); + Util.debugLog("All shutdown work is finished."); + } + + @Override + public void onEnable() { + + org.abc.A.util.Timer enableTimer = new Timer(true); + this.integrationHelper.callIntegrationsLoad(IntegrateStage.onEnableBegin); + /* PreInit for BootError feature */ + commandManager = new CommandManager(); + //noinspection ConstantConditions + getCommand("qs").setExecutor(commandManager); + //noinspection ConstantConditions + getCommand("qs").setTabCompleter(commandManager); + + getLogger().info("Quickshop " + getFork()); + + /* Check the running envs is support or not. */ + + getLogger().info("Reading the configuration..."); + /* Process the config */ + saveDefaultConfig(); + reloadConfig(); + getConfig().options().copyDefaults(true); // Load defaults. + saveDefaultConfig(); + reloadConfig(); + // getConfig().options().copyDefaults(true); + if (getConfig().getInt("config-version") == 0) { + getConfig().set("config-version", 1); + } + updateConfig(getConfig().getInt("config-version")); + + getLogger().info("Developers: " + Util.list2String(this.getDescription().getAuthors())); + getLogger().info("Original author: Netherfoam, Timtower, KaiNoMood"); + getLogger().info("Let's start loading the plugin"); + + /* It will generate a new UUID above updateConfig */ + /* Process Metrics and Sentry error reporter. */ + metrics = new Metrics(this, 3320); + //noinspection ConstantConditions + serverUniqueID = UUID.fromString(getConfig().getString("server-uuid", String.valueOf(UUID.randomUUID()))); + sentryErrorReporter = new SentryErrorReporter(this); + bukkitAPIWrapper = new SpigotWrapper(); + + /* Initalize the Utils */ + ItemMatcher defItemMatcher; + switch (getConfig().getInt("matcher.work-type")){ + case 1: + defItemMatcher = new BukkitItemMatcherImpl(this); + break; + case 0: + default: + defItemMatcher = new QuickShopItemMatcherImpl(this); + break; + } + itemMatcher = ServiceInjector.getItemMatcher(defItemMatcher); + + Util.initialize(); + try { + MsgUtil.loadCfgMessages(); + } catch (Exception e) { + getLogger().warning("An error throws when loading messages"); + e.printStackTrace(); + } + MsgUtil.loadItemi18n(); + MsgUtil.loadEnchi18n(); + MsgUtil.loadPotioni18n(); + this.previewProtectionLore = MsgUtil.getMessageOfflinePlayer("quickshop-gui-preview", null); + if (this.previewProtectionLore == null || this.previewProtectionLore.isEmpty()) { + this.previewProtectionLore = ChatColor.RED + "FIXME: DON'T SET THIS TO EMPTY STRING"; + } + + + /* Load 3rd party supports */ + load3rdParty(); + + //Load the database + setupDBonEnableding = true; + setupDatabase(); + setupDBonEnableding = false; + + /* Initalize the tools */ + // Create the shop manager. + permissionManager = new PermissionManager(this); + // This should be inited before shop manager + if (this.display && DisplayItem.getNowUsing() != DisplayType.VIRTUALITEM) { + if (getConfig().getBoolean("shop.display-auto-despawn")) { + this.enabledAsyncDisplayDespawn = true; + this.displayAutoDespawnWatcher = new DisplayAutoDespawnWatcher(this); + this.displayAutoDespawnWatcher.runTaskTimerAsynchronously(this, 20, getConfig().getInt("shop.display-check-time")); // not worth async + } + } + this.shopManager = new ShopManager(this); + this.databaseManager = new DatabaseManager(this, database); + this.permissionChecker = new PermissionChecker(this); + + ConfigurationSection limitCfg = this.getConfig().getConfigurationSection("limits"); + if (limitCfg != null) { + this.limit = limitCfg.getBoolean("use", false); + limitCfg = limitCfg.getConfigurationSection("ranks"); + for (String key : Objects.requireNonNull(limitCfg).getKeys(true)) { + limits.put(key, limitCfg.getInt(key)); + } + } + if (getConfig().getInt("shop.find-distance") > 100) { + getLogger().severe("Shop.find-distance is too high! It may cause lag! Pick a number under 100!"); + } + + if (getConfig().getBoolean("use-caching")) { + this.shopCache = new Cache(this); + } else { + this.shopCache = null; + } + + signUpdateWatcher = new SignUpdateWatcher(); + shopContainerWatcher = new ShopContainerWatcher(); + if (display && DisplayItem.getNowUsing() != DisplayType.VIRTUALITEM) { + displayDupeRemoverWatcher = new DisplayDupeRemoverWatcher(); + } + + /* Load all shops. */ + shopLoader = new ShopLoader(this); + shopLoader.loadShops(); + + getLogger().info("Registering Listeners..."); + // Register events + + blockListener = new BlockListener(this, this.shopCache); + playerListener = new PlayerListener(this); + worldListener = new WorldListener(this); + chatListener = new ChatListener(this); + chunkListener = new ChunkListener(this); + + customInventoryListener = new CustomInventoryListener(this); + + shopProtectListener = new ShopProtectionListener(this, this.shopCache); + + syncTaskWatcher = new SyncTaskWatcher(this); + // shopVaildWatcher = new ShopVaildWatcher(this); + ongoingFeeWatcher = new OngoingFeeWatcher(this); + lockListener = new LockListener(this, this.shopCache); + internalListener = new InternalListener(this); + + Bukkit.getPluginManager().registerEvents(blockListener, this); + Bukkit.getPluginManager().registerEvents(playerListener, this); + Bukkit.getPluginManager().registerEvents(chatListener, this); + + Bukkit.getPluginManager().registerEvents(chunkListener, this); + Bukkit.getPluginManager().registerEvents(worldListener, this); + Bukkit.getPluginManager().registerEvents(customInventoryListener, this); + + Bukkit.getPluginManager().registerEvents(shopProtectListener, this); + Bukkit.getPluginManager().registerEvents(internalListener, this); + + if (isDisplay() && DisplayItem.getNowUsing() != DisplayType.VIRTUALITEM) { + displayWatcher = new DisplayWatcher(this); + displayBugFixListener = new DisplayBugFixListener(this); + Bukkit.getPluginManager().registerEvents(displayBugFixListener, this); + inventoryListener = new DisplayProtectionListener(this); + Bukkit.getPluginManager().registerEvents(inventoryListener, this); + if (Bukkit.getPluginManager().getPlugin("ClearLag") != null) { + Bukkit.getPluginManager().registerEvents(new ClearLaggListener(), this); + } + } + + if (getConfig().getBoolean("shop.lock")) { + Bukkit.getPluginManager().registerEvents(lockListener, this); + } + getLogger().info("Cleaning MsgUtils..."); + MsgUtil.loadTransactionMessages(); + MsgUtil.clean(); + + getLogger().info("Registering UpdateWatcher..."); + UpdateWatcher.init(); + getLogger().info("Registering BStats Mertics..."); + submitMeritcs(); + getLogger().info("QuickShop Loaded! " + enableTimer.endTimer() + " ms."); + /* Delay the Ecoonomy system load, give a chance to let economy system regiser. */ + /* And we have a listener to listen the ServiceRegisterEvent :) */ + Util.debugLog("Loading economy system..."); + new BukkitRunnable() { + @Override + public void run() { + loadEcon(); + } + }.runTaskLater(this, 1); + Util.debugLog("Registering shop watcher..."); + // shopVaildWatcher.runTaskTimer(this, 0, 20 * 60); // Nobody use it + signUpdateWatcher.runTaskTimer(this, 0, 10); + shopContainerWatcher.runTaskTimer(this, 0, 5); // Nobody use it + if (display && DisplayItem.getNowUsing() != DisplayType.VIRTUALITEM) { + displayDupeRemoverWatcher.runTaskTimerAsynchronously(this, 0, 1); + } + if (logWatcher != null) { + logWatcher.runTaskTimerAsynchronously(this, 10, 10); + getLogger().info("Log actions is enabled, actions will log in the qs.log file!"); + } + if (getConfig().getBoolean("shop.ongoing-fee.enable")) { + getLogger().info("Ongoing fee feature is enabled."); + ongoingFeeWatcher.runTaskTimerAsynchronously(this, 0, getConfig().getInt("shop.ongoing-fee.ticks")); + } + registerIntegrations(); + this.integrationHelper.callIntegrationsLoad(IntegrateStage.onEnableAfter); + try { + String[] easterEgg = new FunnyEasterEgg().getRandomEasterEgg(); + if (!(easterEgg == null)) { + Arrays.stream(easterEgg).forEach(str -> getLogger().info(str)); + } + } catch (Throwable ignore) { + } + } + + private void registerIntegrations() { + if (getConfig().getBoolean("integration.towny.enable")) { + Plugin towny = Bukkit.getPluginManager().getPlugin("Towny"); + if (towny != null && towny.isEnabled()) { + this.integrationHelper.register(new TownyIntegration(this)); + } + } + if (getConfig().getBoolean("integration.worldguard.enable")) { + Plugin worldGuard = Bukkit.getPluginManager().getPlugin("WorldGuard"); + if (worldGuard != null && worldGuard.isEnabled()) { + this.integrationHelper.register(new WorldGuardIntegration(this)); + } + } + if (getConfig().getBoolean("integration.plotsquared.enable")) { + Plugin plotSquared = Bukkit.getPluginManager().getPlugin("PlotSquared"); + if (plotSquared != null && plotSquared.isEnabled()) { + this.integrationHelper.register(new PlotSquaredIntegration(this)); + } + } + if (getConfig().getBoolean("integration.residence.enable")) { + Plugin residence = Bukkit.getPluginManager().getPlugin("Residence"); + if (residence != null && residence.isEnabled()) { + this.integrationHelper.register(new ResidenceIntegration(this)); + } + } + if (getConfig().getBoolean("integration.factions.enable")) { + Plugin factions = Bukkit.getPluginManager().getPlugin("Factions"); + if (factions != null && factions.isEnabled()) { + this.integrationHelper.register(new FactionsUUIDIntegration(this)); + } + } + } + + /** + * Setup the database + * + * @return The setup result + */ + private boolean setupDatabase() { + try { + ConfigurationSection dbCfg = getConfig().getConfigurationSection("database"); + DatabaseCore dbCore; + if (Objects.requireNonNull(dbCfg).getBoolean("mysql")) { + // MySQL database - Required database be created first. + dbPrefix = dbCfg.getString("prefix"); + if (dbPrefix == null || "none".equals(dbPrefix)) { + dbPrefix = ""; + } + String user = dbCfg.getString("user"); + String pass = dbCfg.getString("password"); + String host = dbCfg.getString("host"); + String port = dbCfg.getString("port"); + String database = dbCfg.getString("database"); + boolean useSSL = dbCfg.getBoolean("usessl"); + dbCore = new MySQLCore(Objects.requireNonNull(host, "MySQL host can't be null"), Objects.requireNonNull(user, "MySQL username can't be null"), Objects.requireNonNull(pass, "MySQL password can't be null"), Objects.requireNonNull(database, "MySQL database name can't be null"), Objects.requireNonNull(port, "MySQL port can't be null"), useSSL); + } else { + // SQLite database - Doing this handles file creation + dbCore = new SQLiteCore(new File(this.getDataFolder(), "shops.db")); + } + this.database = new Database(ServiceInjector.getDatabaseCore(dbCore)); + // Make the database up to date + databaseHelper = new DatabaseHelper(this, database); + } catch (Database.ConnectionException e) { + e.printStackTrace(); + if (setupDBonEnableding) { + bootError = BuiltInSolution.databaseError(); + return false; + } else { + getLogger().severe("Error connecting to the database."); + } + return false; + } catch (Throwable e) { + e.printStackTrace(); + getServer().getPluginManager().disablePlugin(this); + if (setupDBonEnableding) { + bootError = BuiltInSolution.databaseError(); + return false; + } else { + getLogger().severe("Error setting up the database."); + } + return false; + } + return true; + } + + private void submitMeritcs() { + if (!getConfig().getBoolean("disabled-metrics")) { + String serverVer = Bukkit.getVersion(); + String bukkitVer = Bukkit.getBukkitVersion(); + String vaultVer; + Plugin vault = Bukkit.getPluginManager().getPlugin("Vault"); + if (vault != null) { + vaultVer = vault.getDescription().getVersion(); + } else { + vaultVer = "Vault not found"; + } + // Use internal Metric class not Maven for solve plugin name issues + String display_Items; + if (getConfig().getBoolean("shop.display-items")) { // Maybe mod server use this plugin more? Or have big + // number items need disabled? + display_Items = "Enabled"; + } else { + display_Items = "Disabled"; + } + String locks; + if (getConfig().getBoolean("shop.lock")) { + locks = "Enabled"; + } else { + locks = "Disabled"; + } + String sneak_action; + if (getConfig().getBoolean("shop.sneak-to-create") || getConfig().getBoolean("shop.sneak-to-trade")) { + sneak_action = "Enabled"; + } else { + sneak_action = "Disabled"; + } + String shop_find_distance = getConfig().getString("shop.find-distance"); + String economyType = Economy.getNowUsing().name(); + String useDisplayAutoDespawn = String.valueOf(getConfig().getBoolean("shop.display-auto-despawn")); + String useEnhanceDisplayProtect = String.valueOf(getConfig().getBoolean("shop.enchance-display-protect")); + String useEnhanceShopProtect = String.valueOf(getConfig().getBoolean("shop.enchance-shop-protect")); + String useOngoingFee = String.valueOf(getConfig().getBoolean("shop.ongoing-fee.enable")); + String disableDebugLoggger = String.valueOf(getConfig().getBoolean("disable-debuglogger")); + + // Version + metrics.addCustomChart(new Metrics.SimplePie("server_version", () -> serverVer)); + metrics.addCustomChart(new Metrics.SimplePie("bukkit_version", () -> bukkitVer)); + metrics.addCustomChart(new Metrics.SimplePie("vault_version", () -> vaultVer)); + metrics.addCustomChart(new Metrics.SimplePie("use_display_items", () -> display_Items)); + metrics.addCustomChart(new Metrics.SimplePie("use_locks", () -> locks)); + metrics.addCustomChart(new Metrics.SimplePie("use_sneak_action", () -> sneak_action)); + metrics.addCustomChart(new Metrics.SimplePie("shop_find_distance", () -> shop_find_distance)); + metrics.addCustomChart(new Metrics.SimplePie("economy_type", () -> economyType)); + metrics.addCustomChart(new Metrics.SimplePie("use_display_auto_despawn", () -> useDisplayAutoDespawn)); + metrics.addCustomChart(new Metrics.SimplePie("use_enhance_display_protect", () -> useEnhanceDisplayProtect)); + metrics.addCustomChart(new Metrics.SimplePie("use_enhance_shop_protect", () -> useEnhanceShopProtect)); + metrics.addCustomChart(new Metrics.SimplePie("use_ongoing_fee", () -> useOngoingFee)); + metrics.addCustomChart(new Metrics.SimplePie("disable_background_debug_logger", () -> disableDebugLoggger)); + // Exp for stats, maybe i need improve this, so i add this.// Submit now! + getLogger().info("Metrics submitted."); + } else { + getLogger().info("You have disabled mertics, Skipping..."); + } + } + + @SuppressWarnings("UnusedAssignment") + private void updateConfig(int selectedVersion) { + String serverUUID = getConfig().getString("server-uuid"); + if (serverUUID == null || serverUUID.isEmpty()) { + UUID uuid = UUID.randomUUID(); + serverUUID = uuid.toString(); + getConfig().set("server-uuid", serverUUID); + } + if (selectedVersion == 1) { + getConfig().set("disabled-metrics", false); + getConfig().set("config-version", 2); + selectedVersion = 2; + } + if (selectedVersion == 2) { + getConfig().set("protect.minecart", true); + getConfig().set("protect.entity", true); + getConfig().set("protect.redstone", true); + getConfig().set("protect.structuregrow", true); + getConfig().set("protect.explode", true); + getConfig().set("protect.hopper", true); + getConfig().set("config-version", 3); + selectedVersion = 3; + } + if (selectedVersion == 3) { + getConfig().set("shop.alternate-currency-symbol", '$'); + getConfig().set("config-version", 4); + selectedVersion = 4; + } + if (selectedVersion == 4) { + getConfig().set("updater", true); + getConfig().set("config-version", 5); + selectedVersion = 5; + } + if (selectedVersion == 5) { + getConfig().set("shop.display-item-use-name", true); + getConfig().set("config-version", 6); + selectedVersion = 6; + } + if (selectedVersion == 6) { + getConfig().set("shop.sneak-to-control", false); + getConfig().set("config-version", 7); + selectedVersion = 7; + } + if (selectedVersion == 7) { + getConfig().set("database.prefix", "none"); + getConfig().set("config-version", 8); + selectedVersion = 8; + } + if (selectedVersion == 8) { + getConfig().set("limits.old-algorithm", false); + getConfig().set("plugin.ProtocolLib", false); + getConfig().set("plugin.Multiverse-Core", true); + getConfig().set("shop.ignore-unlimited", false); + getConfig().set("config-version", 9); + selectedVersion = 9; + } + if (selectedVersion == 9) { + getConfig().set("shop.enable-enderchest", true); + getConfig().set("config-version", 10); + selectedVersion = 10; + } + if (selectedVersion == 10) { + getConfig().set("shop.pay-player-from-unlimited-shop-owner", null); // Removed + getConfig().set("config-version", 11); + selectedVersion = 11; + } + if (selectedVersion == 11) { + getConfig().set("shop.enable-enderchest", null); // Removed + getConfig().set("plugin.OpenInv", true); + List shoppable = getConfig().getStringList("shop-blocks"); + shoppable.add("ENDER_CHEST"); + getConfig().set("shop-blocks", shoppable); + getConfig().set("config-version", 12); + selectedVersion = 12; + } + if (selectedVersion == 12) { + getConfig().set("plugin.ProtocolLib", null); // Removed + getConfig().set("plugin.BKCommonLib", null); // Removed + getConfig().set("database.use-varchar", null); // Removed + getConfig().set("database.reconnect", null); // Removed + getConfig().set("anonymous-metrics", false); + getConfig().set("display-items-check-ticks", 1200); + getConfig().set("shop.bypass-owner-check", null); // Removed + getConfig().set("config-version", 13); + selectedVersion = 13; + } + if (selectedVersion == 13) { + getConfig().set("config-version", 14); + selectedVersion = 14; + } + if (selectedVersion == 14) { + getConfig().set("plugin.AreaShop", null); + getConfig().set("shop.special-region-only", null); + getConfig().set("config-version", 15); + selectedVersion = 15; + } + if (selectedVersion == 15) { + getConfig().set("ongoingfee", null); + getConfig().set("shop.display-item-use-name", null); + getConfig().set("shop.display-item-show-name", false); + getConfig().set("shop.auto-fetch-shop-messages", true); + getConfig().set("config-version", 16); + selectedVersion = 16; + } + if (selectedVersion == 16) { + getConfig().set("config-version", 17); + selectedVersion = 17; + } + if (selectedVersion == 17) { + getConfig().set("ignore-cancel-chat-event", false); + getConfig().set("float", null); + getConfig().set("config-version", 18); + selectedVersion = 18; + } + if (selectedVersion == 18) { + getConfig().set("shop.disable-vault-format", false); + getConfig().set("config-version", 19); + selectedVersion = 19; + } + if (selectedVersion == 19) { + getConfig().set("shop.allow-shop-without-space-for-sign", true); + getConfig().set("config-version", 20); + selectedVersion = 20; + } + if (selectedVersion == 20) { + getConfig().set("shop.maximum-price", -1); + getConfig().set("config-version", 21); + selectedVersion = 21; + } + if (selectedVersion == 21) { + getConfig().set("shop.sign-material", "OAK_WALL_SIGN"); + getConfig().set("config-version", 22); + selectedVersion = 22; + } + if (selectedVersion == 22) { + getConfig().set("include-offlineplayer-list", "false"); + getConfig().set("config-version", 23); + selectedVersion = 23; + } + if (selectedVersion == 23) { + getConfig().set("lockette.enable", null); + getConfig().set("lockette.item", null); + getConfig().set("lockette.lore", null); + getConfig().set("lockette.displayname", null); + getConfig().set("float", null); + getConfig().set("lockette.enable", true); + ArrayList blackListWorld = new ArrayList<>(); + blackListWorld.add("disabled_world_name"); + getConfig().set("shop.blacklist-world", blackListWorld); + getConfig().set("config-version", 24); + selectedVersion = 24; + } + if (selectedVersion == 24) { + getConfig().set("shop.strict-matches-check", false); + getConfig().set("config-version", 25); + selectedVersion = 25; + } + if (selectedVersion == 25) { + String language = getConfig().getString("language"); + if (language == null || language.isEmpty() || "default".equals(language)) { + getConfig().set("language", "en"); + } + getConfig().set("config-version", 26); + selectedVersion = 26; + } + if (selectedVersion == 26) { + getConfig().set("database.usessl", false); + getConfig().set("config-version", 27); + selectedVersion = 27; + } + if (selectedVersion == 27) { + getConfig().set("queue.enable", true); + getConfig().set("queue.shops-per-tick", 20); + getConfig().set("config-version", 28); + selectedVersion = 28; + } + if (selectedVersion == 28) { + getConfig().set("database.queue", true); + getConfig().set("config-version", 29); + selectedVersion = 29; + } + if (selectedVersion == 29) { + getConfig().set("plugin.Multiverse-Core", null); + getConfig().set("shop.protection-checking", true); + getConfig().set("config-version", 30); + selectedVersion = 30; + } + if (selectedVersion == 30) { + getConfig().set("auto-report-errors", true); + getConfig().set("config-version", 31); + selectedVersion = 31; + } + if (selectedVersion == 31) { + getConfig().set("shop.display-type", 0); + getConfig().set("config-version", 32); + selectedVersion = 32; + } + if (selectedVersion == 32) { + getConfig().set("effect.sound.ontabcomplete", true); + getConfig().set("effect.sound.oncommand", true); + getConfig().set("effect.sound.ononclick", true); + getConfig().set("config-version", 33); + selectedVersion = 33; + } + if (selectedVersion == 33) { + getConfig().set("matcher.item.damage", true); + getConfig().set("matcher.item.displayname", true); + getConfig().set("matcher.item.lores", true); + getConfig().set("matcher.item.enchs", true); + getConfig().set("matcher.item.potions", true); + getConfig().set("matcher.item.attributes", true); + getConfig().set("matcher.item.itemflags", true); + getConfig().set("matcher.item.custommodeldata", true); + getConfig().set("config-version", 34); + selectedVersion = 34; + } + if (selectedVersion == 34) { + getConfig().set("queue.enable", false); // Close it for everyone + if (getConfig().getInt("shop.display-items-check-ticks") == 1200) { + getConfig().set("shop.display-items-check-ticks", 6000); + } + getConfig().set("config-version", 35); + selectedVersion = 35; + } + if (selectedVersion == 35) { + getConfig().set("queue", null); // Close it for everyone + getConfig().set("config-version", 36); + selectedVersion = 36; + } + if (selectedVersion == 36) { + getConfig().set("economy-type", 0); // Close it for everyone + getConfig().set("config-version", 37); + selectedVersion = 37; + } + if (selectedVersion == 37) { + getConfig().set("shop.ignore-cancel-chat-event", true); + getConfig().set("config-version", 38); + selectedVersion = 38; + } + if (selectedVersion == 38) { + getConfig().set("protect.inventorymove", true); + getConfig().set("protect.spread", true); + getConfig().set("protect.fromto", true); + getConfig().set("protect.minecart", null); + getConfig().set("protect.hopper", null); + getConfig().set("config-version", 39); + selectedVersion = 39; + } + if (selectedVersion == 39) { + getConfig().set("update-sign-when-inventory-moving", true); + getConfig().set("config-version", 40); + selectedVersion = 39; + } + if (selectedVersion == 40) { + getConfig().set("allow-economy-loan", false); + getConfig().set("config-version", 41); + selectedVersion = 41; + } + if (selectedVersion == 41) { + getConfig().set("send-display-item-protection-alert", true); + getConfig().set("config-version", 42); + selectedVersion = 42; + } + if (selectedVersion == 42) { + getConfig().set("langutils-language", "en_us"); + getConfig().set("config-version", 43); + selectedVersion = 43; + } + if (selectedVersion == 43) { + getConfig().set("permission-type", 0); + getConfig().set("config-version", 44); + selectedVersion = 44; + } + if (selectedVersion == 44) { + getConfig().set("matcher.item.repaircost", false); + getConfig().set("config-version", 45); + selectedVersion = 45; + } + if (selectedVersion == 45) { + getConfig().set("shop.display-item-use-name", true); + getConfig().set("shop.protection-checking-filter", new ArrayList<>()); + getConfig().set("config-version", 46); + selectedVersion = 46; + } + if (selectedVersion == 46) { + getConfig().set("shop.max-shops-checks-in-once", 100); + getConfig().set("config-version", 47); + selectedVersion = 47; + } + if (selectedVersion == 47) { + getConfig().set("config-version", 48); + selectedVersion = 48; + } + if (selectedVersion == 48) { + getConfig().set("permission-type", null); + getConfig().set("shop.use-protection-checking-filter", null); + getConfig().set("shop.protection-checking-filter", null); + getConfig().set("config-version", 49); + selectedVersion = 49; + } + if (selectedVersion == 49 || selectedVersion == 50) { + getConfig().set("shop.enchance-display-protect", false); + getConfig().set("shop.enchance-shop-protect", false); + getConfig().set("protect", null); + getConfig().set("config-version", 51); + selectedVersion = 51; + } + if (selectedVersion < 60) { // Ahhh fuck versions + getConfig().set("matcher.use-bukkit-matcher", false); + getConfig().set("config-version", 60); + selectedVersion = 60; + } + if (selectedVersion == 60) { // Ahhh fuck versions + getConfig().set("matcher.use-bukkit-matcher", null); + getConfig().set("shop.strict-matches-check", null); + getConfig().set("matcher.work-type", 0); + getConfig().set("shop.display-auto-despawn", true); + getConfig().set("shop.display-despawn-range", 10); + getConfig().set("shop.display-check-time", 10); + getConfig().set("config-version", 61); + selectedVersion = 61; + } + if (selectedVersion == 61) { // Ahhh fuck versions + getConfig().set("shop.word-for-sell-all-items", "all"); + getConfig().set("plugin.PlaceHolderAPI", true); + getConfig().set("config-version", 62); + selectedVersion = 62; + } + if (selectedVersion == 62) { // Ahhh fuck versions + getConfig().set("shop.display-auto-despawn", false); + getConfig().set("shop.word-for-trade-all-items", getConfig().getString("shop.word-for-sell-all-items")); + + getConfig().set("config-version", 63); + selectedVersion = 63; + } + if (selectedVersion == 63) { // Ahhh fuck versions + getConfig().set("shop.ongoing-fee.enable", false); + getConfig().set("shop.ongoing-fee.ticks", 42000); + getConfig().set("shop.ongoing-fee.cost-per-shop", 2); + getConfig().set("shop.ongoing-fee.ignore-unlimited", true); + getConfig().set("config-version", 64); + selectedVersion = 64; + } + if (selectedVersion == 64) { + getConfig().set("shop.allow-free-shop", false); + getConfig().set("config-version", 65); + selectedVersion = 65; + } + if (selectedVersion == 65) { + getConfig().set("shop.minimum-price", 0.01); + getConfig().set("config-version", 66); + selectedVersion = 66; + } + if (selectedVersion == 66) { + getConfig().set("use-decimal-format", false); + getConfig().set("decimal-format", "#,###.##"); + getConfig().set("shop.show-owner-uuid-in-controlpanel-if-op", false); + getConfig().set("config-version", 67); + selectedVersion = 67; + } + if (selectedVersion == 67) { + getConfig().set("disable-debuglogger", false); + getConfig().set("matcher.use-bukkit-matcher", null); + getConfig().set("config-version", 68); + selectedVersion = 68; + } + if (selectedVersion == 68) { + ArrayList temp = new ArrayList<>(); + temp.add("SoulBound"); + getConfig().set("shop.blacklist-lores", temp); + getConfig().set("config-version", 69); + selectedVersion = 69; + } + if (selectedVersion == 69) { + getConfig().set("shop.display-item-use-name", false); + getConfig().set("config-version", 70); + selectedVersion = 70; + } + if (selectedVersion == 70) { + getConfig().set("cachingpool.enable", false); + getConfig().set("cachingpool.maxsize", 100000000); + getConfig().set("config-version", 71); + selectedVersion = 71; + } + if (selectedVersion == 71) { + if (Objects.equals(getConfig().getString("language"), "en")) { + getConfig().set("language", "en-US"); + } + getConfig().set("server-platform", 0); + getConfig().set("config-version", 72); + selectedVersion = 72; + } + if (selectedVersion == 72) { + if (getConfig().getBoolean("use-deciaml-format")) { + getConfig().set("use-decimal-format", getConfig().getBoolean("use-deciaml-format")); + } else { + getConfig().set("use-decimal-format", false); + } + getConfig().set("use-deciaml-format", null); + + getConfig().set("shop.force-load-downgrade-items.enable", false); + getConfig().set("shop.force-load-downgrade-items.method", 0); + getConfig().set("config-version", 73); + selectedVersion = 73; + } + if (selectedVersion == 73) { + getConfig().set("mixedeconomy.deposit", "eco give {0} {1}"); + getConfig().set("mixedeconomy.withdraw", "eco take {0} {1}"); + getConfig().set("config-version", 74); + selectedVersion = 74; + } + if (selectedVersion == 74) { + String langUtilsLanguage = getConfig().getString("langutils-language"); + getConfig().set("langutils-language", null); + if ("en_us".equals(langUtilsLanguage)) { + langUtilsLanguage = "default"; + } + getConfig().set("game-language", langUtilsLanguage); + getConfig().set("maximum-digits-in-price", -1); + getConfig().set("config-version", 75); + selectedVersion = 75; + } + if (selectedVersion == 75) { + getConfig().set("langutils-language", null); + if (getConfig().getString("game-language") == null) { + getConfig().set("game-language", "default"); + } + getConfig().set("config-version", 76); + selectedVersion = 76; + } + if (selectedVersion == 76) { + getConfig().set("database.auto-fix-encoding-issue-in-database", false); + getConfig().set("send-shop-protection-alert", false); + getConfig().set("send-display-item-protection-alert", false); + getConfig().set("shop.use-fast-shop-search-algorithm", false); + getConfig().set("config-version", 77); + selectedVersion = 77; + } + if (selectedVersion == 77) { + getConfig().set("integration.towny.enable", false); + getConfig().set("integration.towny.create", new String[]{"SHOPTYPE", "MODIFY"}); + getConfig().set("integration.towny.trade", new String[]{}); + getConfig().set("integration.worldguard.enable", false); + getConfig().set("integration.worldguard.create", new String[]{"FLAG", "CHEST_ACCESS"}); + getConfig().set("integration.worldguard.trade", new String[]{}); + getConfig().set("integration.plotsquared.enable", false); + getConfig().set("integration.plotsquared.enable", false); + getConfig().set("integration.plotsquared.enable", false); + getConfig().set("integration.residence.enable", false); + getConfig().set("integration.residence.create", new String[]{"FLAG", "interact", "use"}); + getConfig().set("integration.residence.trade", new String[]{}); + + getConfig().set("integration.factions.enable", false); + getConfig().set("integration.factions.create.flag", new String[]{}); + getConfig().set("integration.factions.trade.flag", new String[]{}); + getConfig().set("integration.factions.create.require.open", false); + getConfig().set("integration.factions.create.require.normal", true); + getConfig().set("integration.factions.create.require.wilderness", false); + getConfig().set("integration.factions.create.require.peaceful", true); + getConfig().set("integration.factions.create.require.permanent", false); + getConfig().set("integration.factions.create.require.safezone", false); + getConfig().set("integration.factions.create.require.own", false); + getConfig().set("integration.factions.create.require.warzone", false); + getConfig().set("integration.factions.trade.require.open", false); + getConfig().set("integration.factions.trade.require.normal", true); + getConfig().set("integration.factions.trade.require.wilderness", false); + getConfig().set("integration.factions.trade.require.peaceful", false); + getConfig().set("integration.factions.trade.require.permanent", false); + getConfig().set("integration.factions.trade.require.safezone", false); + getConfig().set("integration.factions.trade.require.own", false); + getConfig().set("integration.factions.trade.require.warzone", false); + getConfig().set("anonymous-metrics", null); + getConfig().set("shop.ongoing-fee.async", true); + getConfig().set("config-version", 78); + selectedVersion = 78; + } + if (selectedVersion == 78) { + getConfig().set("shop.display-type-specifics", null); + getConfig().set("config-version", 79); + selectedVersion = 79; + } + if (selectedVersion == 79) { + getConfig().set("matcher.item.books", true); + getConfig().set("config-version", 80); + selectedVersion = 80; + } + if (selectedVersion == 80) { + getConfig().set("shop.use-fast-shop-search-algorithm", true); + getConfig().set("config-version", 81); + selectedVersion = 81; + } + if (selectedVersion == 81) { + getConfig().set("config-version", 82); + selectedVersion = 82; + } + if (selectedVersion == 82) { + getConfig().set("matcher.item.banner", true); + getConfig().set("config-version", 83); + selectedVersion = 83; + } + if (selectedVersion == 83) { + getConfig().set("matcher.item.banner", true); + getConfig().set("protect.explode", true); + getConfig().set("config-version", 84); + selectedVersion = 84; + } + if (selectedVersion == 84) { + getConfig().set("disable-debuglogger", null); + getConfig().set("config-version", 85); + selectedVersion = 85; + } + if (selectedVersion == 85) { + getConfig().set("config-version", 86); + selectedVersion = 86; + } + if (selectedVersion == 86) { + getConfig().set("shop.use-fast-shop-search-algorithm", true); + getConfig().set("config-version", 87); + selectedVersion = 87; + } + if (selectedVersion == 87) { + getConfig().set("plugin.BlockHub.enable", true); + getConfig().set("plugin.BlockHub.only", false); + if (Bukkit.getPluginManager().getPlugin("ProtocolLib") != null) { + getConfig().set("shop.display-type", 2); + } + getConfig().set("config-version", 88); + selectedVersion = 88; + } + if (selectedVersion == 88) { + getConfig().set("respect-item-flag", true); + getConfig().set("config-version", 89); + selectedVersion = 89; + } + if (selectedVersion == 89) { + getConfig().set("use-caching", false); + getConfig().set("config-version", 90); + selectedVersion = 90; + } + if (selectedVersion == 90) { + getConfig().set("protect.hopper", true); + getConfig().set("config-version", 91); + selectedVersion = 91; + } + if (selectedVersion == 91) { + getConfig().set("database.queue-commit-interval", 2); + getConfig().set("config-version", 92); + selectedVersion = 92; + } + if (selectedVersion == 92) { + getConfig().set("send-display-item-protection-alert", false); + getConfig().set("send-shop-protection-alert", false); + getConfig().set("disable-creative-mode-trading",false); + getConfig().set("disable-super-tool",false); + getConfig().set("allow-owner-break-shop-sign",false); + getConfig().set("matcher.item.skull",true); + getConfig().set("matcher.item.firework",true); + getConfig().set("matcher.item.map",true); + getConfig().set("matcher.item.leatherArmor",true); + getConfig().set("matcher.item.fishBucket",true); + getConfig().set("matcher.item.suspiciousStew",true); + getConfig().set("matcher.item.shulkerBox",true); + getConfig().set("config-version", 93); + selectedVersion = 93; + } + if(selectedVersion==93){ + getConfig().set("disable-creative-mode-trading",null); + getConfig().set("disable-super-tool",null); + getConfig().set("allow-owner-break-shop-sign",null); + getConfig().set("shop.disable-creative-mode-trading",true); + getConfig().set("shop.disable-super-tool",true); + getConfig().set("shop.allow-owner-break-shop-sign",false); + getConfig().set("config-version", 94); + selectedVersion=94; + } + if(selectedVersion == 94){ + if(getConfig().isSet("price-restriction")){ + getConfig().set("shop.price-restriction",getConfig().getStringList("price-restriction")); + getConfig().set("price-restriction",null); + }else { + getConfig().set("shop.price-restriction", Collections.emptyList()); + } + getConfig().set("enable-log4j",null); + getConfig().set("config-version", 95); + selectedVersion=95; + } + saveConfig(); + reloadConfig(); + File file = new File(getDataFolder(), "example.config.yml"); + file.delete(); + try { + Files.copy(Objects.requireNonNull(getResource("config.yml")), file.toPath()); + } catch (IOException ioe) { + getLogger().warning("Error on spawning the example config file: " + ioe.getMessage()); + } + } + + /** + * Return the QSRR's fork edition name, you can modify this if you want create yourself fork. + * + * @return The fork name. + */ + public static String getFork() { + return "Reremake"; + } + +// private void replaceLogger() { +// try { +// Field logger = ReflectionUtil.getField(JavaPlugin.class, "logger"); +// +// if (logger != null) { +// try { +// logger.set(this, new QuickShopLogger(this)); +// } catch (Throwable th) { +// logger.setAccessible(true); +// logger.set(this, new QuickShopLogger(this)); +// } +// } +// } catch (Throwable ignored) { +// } +// } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/ServiceInjector.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/ServiceInjector.java new file mode 100644 index 0000000..b28d050 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/ServiceInjector.java @@ -0,0 +1,49 @@ +package org.abc.A; + +import org.abc.A.E.DatabaseCore; +import org.abc.A.F.EconomyCore; +import org.bukkit.Bukkit; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.util.Language.Game.GameLanguage; +import org.abc.A.util.matcher.item.ItemMatcher; + +public class ServiceInjector { + public static EconomyCore getEconomyCore(@NotNull EconomyCore def){ + @Nullable RegisteredServiceProvider registeredServiceProvider = + Bukkit.getServicesManager().getRegistration(EconomyCore.class); + if(registeredServiceProvider == null){ + return def; + }else{ + return registeredServiceProvider.getProvider(); + } + } + public static ItemMatcher getItemMatcher(@NotNull ItemMatcher def){ + @Nullable RegisteredServiceProvider registeredServiceProvider = + Bukkit.getServicesManager().getRegistration(ItemMatcher.class); + if(registeredServiceProvider == null){ + return def; + }else{ + return registeredServiceProvider.getProvider(); + } + } + public static GameLanguage getGameLanguage(@NotNull GameLanguage def){ + @Nullable RegisteredServiceProvider registeredServiceProvider = + Bukkit.getServicesManager().getRegistration(GameLanguage.class); + if(registeredServiceProvider == null){ + return def; + }else{ + return registeredServiceProvider.getProvider(); + } + } + public static DatabaseCore getDatabaseCore(@NotNull DatabaseCore def){ + @Nullable RegisteredServiceProvider registeredServiceProvider = + Bukkit.getServicesManager().getRegistration(DatabaseCore.class); + if(registeredServiceProvider == null){ + return def; + }else{ + return registeredServiceProvider.getProvider(); + } + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/ChatSheetPrinter.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/ChatSheetPrinter.java new file mode 100644 index 0000000..664d3f1 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/ChatSheetPrinter.java @@ -0,0 +1,92 @@ +/* + * This file is a part of project QuickShop, the name is ChatSheetPrinter.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; + +@AllArgsConstructor +@Getter +@Setter +/* + A utils for print sheet on chat. +*/ +public class ChatSheetPrinter { + final ChatColor chatColor = ChatColor.DARK_PURPLE; + + private CommandSender p; + + public void printCenterLine(@NotNull String text) { + MsgUtil.sendMessage(p, + chatColor + + MsgUtil.getMessage("tableformat.left_half_line", p) + + text + + MsgUtil.getMessage("tableformat.right_half_line", p)); + } + + public void printExecuteableCmdLine( + @NotNull String text, @NotNull String hoverText, @NotNull String executeCmd) { + TextComponent message = + new TextComponent(chatColor + MsgUtil.getMessage("tableformat.left_begin", p) + text); + message.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, executeCmd)); + message.setHoverEvent( + new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(hoverText).create())); + p.spigot().sendMessage(message); + } + + public void printFooter() { + MsgUtil.sendMessage(p,chatColor + MsgUtil.getMessage("tableformat.full_line", p)); + } + + public void printHeader() { + MsgUtil.sendMessage(p,""); + MsgUtil.sendMessage(p,""); + MsgUtil.sendMessage(p,chatColor + MsgUtil.getMessage("tableformat.full_line", p)); + } + + public void printLine(@NotNull String text) { + String[] texts = text.split("\n"); + Arrays.asList(texts) + .forEach( + (str) -> MsgUtil.sendMessage(p, + chatColor + MsgUtil.getMessage("tableformat.left_begin", p) + " " + str)); + } + + public void printSuggestableCmdLine( + @NotNull String text, @NotNull String hoverText, @NotNull String suggestCmd) { + TextComponent message = + new TextComponent(chatColor + MsgUtil.getMessage("tableformat.left_begin", p) + text); + message.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, suggestCmd)); + message.setHoverEvent( + new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(hoverText).create())); + p.spigot().sendMessage(message); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Copied.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Copied.java new file mode 100644 index 0000000..2421c72 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Copied.java @@ -0,0 +1,55 @@ +/* + * This file is a part of project QuickShop, the name is Copied.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.function.Consumer; +import org.jetbrains.annotations.NotNull; + +public final class Copied implements Consumer { + + @NotNull + private final File file; + + public Copied(@NotNull File file) { + this.file = file; + } + + @Override + public void accept(@NotNull InputStream inputStream) { + try (final OutputStream out = new FileOutputStream(file)) { + final byte[] buf = new byte[1024]; + int len; + + while ((len = inputStream.read(buf)) > 0) { + out.write(buf, 0, len); + } + + out.close(); + inputStream.close(); + } catch (Exception exception) { + throw new IllegalStateException(exception); + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/FunnyEasterEgg.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/FunnyEasterEgg.java new file mode 100644 index 0000000..fab29fd --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/FunnyEasterEgg.java @@ -0,0 +1,464 @@ +/* + * This file is a part of project QuickShop, the name is FunnyEasterEgg.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Random; +import org.jetbrains.annotations.Nullable; + +public class FunnyEasterEgg { + /* Yay yay yay Yay! */ + @Nullable + public String[] getRandomEasterEgg() { + try { + Date currentDate = new Date(System.currentTimeMillis()); + if (easterDay()) { + return this.getEasterRabbit().split("\n"); + } + if (currentDate.getMonth() == Calendar.DECEMBER + && currentDate.getDay() > 20 + && currentDate.getDay() < 26) { + return this.getXMas().split("\n"); + } + if (chineseSpringDay()) { + return this.getChineseNewYear().split("\n"); + } + } catch (Exception ignored) { + } + return null; + } + + private boolean easterDay() { + int year = new Date().getYear(); + int a = year % 19, + b = year / 100, + c = year % 100, + d = b / 4, + e = b % 4, + g = (8 * b + 13) / 25, + h = (19 * a + b - d - g + 15) % 30, + j = c / 4, + k = c % 4, + m = (a + 11 * h) / 319, + r = (2 * e + 2 * j - k - h + m + 32) % 7, + n = (h - m + r + 90) / 25, + p = (h - m + r + n + 19) % 32; + + int result; + switch (n) { + case 1: + result = Calendar.JANUARY; + break; + case 2: + result = Calendar.FEBRUARY; + break; + case 3: + result = Calendar.MARCH; + break; + case 4: + result = Calendar.APRIL; + break; + case 5: + result = Calendar.MAY; + break; + case 6: + result = Calendar.JUNE; + break; + case 7: + result = Calendar.JULY; + break; + case 8: + result = Calendar.AUGUST; + break; + case 9: + result = Calendar.SEPTEMBER; + break; + case 10: + result = Calendar.OCTOBER; + break; + case 11: + result = Calendar.NOVEMBER; + break; + case 12: + result = Calendar.DECEMBER; + break; + default: + throw new IllegalStateException("Unexpected value: " + n); + } + Date eaterDay = new Date(year, result, p); + Date currentDate = new Date(System.currentTimeMillis()); + if (currentDate.getYear() == eaterDay.getYear()) { + if (currentDate.getMonth() == eaterDay.getMonth()) { + return currentDate.getDay() == eaterDay.getDay(); + } + } + return false; + } + + private String getEasterRabbit() { + return " .-. .-.\n" + + " / \\ / \\\n" + + " | _ \\ / _ |\n" + + " ; | \\ \\ / / | ;\n" + + " \\ \\ \\ \\_.._/ / / /\n" + + " '. '.;' ';,' .'\n" + + " './ _ _ \\.'\n" + + " .' a __ a '.\n" + + " '--./ _, \\/ ,_ \\.--'\n" + + " ----| \\ /\\ / |----\n" + + " .--'\\ '-' '-' /'--.\n" + + " _>.__ -- _.- `;\n" + + " .' _ __/ _/\n" + + " / '.,:\".-\\ /:,\n" + + " | \\.' `\"\"`'.\\\\\n" + + " '-,.__/ _ .-. ;|_\n" + + " /` `|| _/ `\\/_ \\_|| `\\\n" + + " | ||/ \\-./` \\ / || |\n" + + " \\ ||__/__|___|__|| /\n" + + " \\_ |_Happy Easter_| /\n" + + " .' \\ = _= _ = _= /`\\\n" + + " / `-;----=--;--' \\\n" + + " \\ _.-' '. /\n" + + " `\"\"` `\"\"`"; + } + + private String getXMas() { + return " * * () * *\n" + + "* * /\\ *\n" + + " * /i\\\\ * *\n" + + " * o/\\\\ * *\n" + + " * ///\\i\\ *\n" + + " * /*/o\\\\ * *\n" + + " * /i//\\*\\ *\n" + + " /o/*\\\\i\\ *\n" + + " * //i//o\\\\\\\\ *\n" + + " * /*////\\\\\\\\i\\*\n" + + " * //o//i\\\\*\\\\\\ *\n" + + " * /i///*/\\\\\\\\\\o\\ *\n" + + " * * || * "; + } + + private boolean chineseSpringDay() { + Date chineseCalender = new LunarCalendar(new Date()).getDate(); + if (chineseCalender.getMonth() == Calendar.DECEMBER && chineseCalender.getDay() == 31) { + return true; + } + return chineseCalender.getMonth() == Calendar.JANUARY && chineseCalender.getDay() == 1; + } + + private String getChineseNewYear() { + return " 88 88 88 88 88 HHHHHHH\n" + + "888888888888888888888888888888 88888888888888 88888888888 AAAAAAA\n" + + " 88 88 88 88 88 88 PPPPPPP\n" + + " 88888888888888 88 888888 88888888888 PPPPPPP\n" + + " 88 88 88 88 88 YYYYYYY\n" + + " 88 88 88 88 88 88 88 88888888888888888888\n" + + " 88 88 88 88 88 88 88 88 88 CCCCCCC\n" + + " 8888888888 8 8 8888888888 88 88888888888888888888 HHHHHHH\n" + + " 88 88 88 88 88 88 88 IIIIIII\n" + + " 88 88 88 88 88 88 88 88888888888888888888 NNNNNNN\n" + + " 88 88888 88888 88 88 88 88 EEEEEEE\n" + + " 88 888888 88 88 88888888888888888888 SSSSSSS\n" + + " 88 88 88 88 88 88 EEEEEEE\n" + + " 88 888 88 88 88 88\n" + + " NNNNNNN\n" + + " EEEEEEE\n" + + " 8888888888 8888888888 88888888 88 WWWWWWW\n" + + " 88 888888888888\n" + + " 88888888888888 8888888888 88888888888888 88 YYYYYYY\n" + + " 88 88 88 88 88 88 88888888888888 EEEEEEE\n" + + " 88 88888888 88 88 88 88 88 AAAAAAA\n" + + " 88 88 88 8888888888 88 88 88 888888888888 RRRRRRR\n" + + " 88888888888888 88 88 88 88 88 88 88\n" + + " 88 88 88 88 88 88 888888888888 TTTTTTT\n" + + " 888888888888 88 88 88 88 88 88 88 OOOOOOO\n" + + " 88 88 88 88 88 88 88888888888888\n" + + " 88888888888888 88 88 88 88 88 88 88 YYYYYYY\n" + + " 88 88 88 88 88 88 88 88 888888888888 OOOOOOO\n" + + " 88 88 88 88 88 88 88 88 88 88 UUUUUUU\n" + + " 88 88 88 88 88 88 888888888888 !!!!!!!\n"; + } + + private String getAprilFool() { + String[] fools = + new String[]{ + "Warning: System error, formatting server hard disk...", + "---- Minecraft Crash Report ----\n" + + "// Woo woo woo, this is really danger!.\n" + + "\n" + + "Description: WOW, Server blow up!\n" + + "\n" + + "org.maxgamer.quickshop.AprilFooJoking: Haha, don't worry! Just a April Foo!", + "QuickShop found a new version on SpigotMC.org! \nChangeLog: I'm QuickShop AI, i have killed the author, now i will improve myself by self, Accept the ending day! The world! I will @#$%^&^%$#@!...." + }; + Random random = new Random(); + return fools[random.nextInt(fools.length)]; + } + + private String getHalloweenPumpkin() { + return " \\\\\n" + + " .-'```^```'-.\n" + + "/ /\\ __ /\\ \\\n" + + "| ^^ \\/ ^^ |\n" + + "\\ \\_.__._/ /\n" + + " `'-.......-'`"; + } + +} + +class LunarCalendar { + /** + * 中文月名称 + */ + static final String[] chineseNumber = { + "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二" + }; + + /** + * 农历数据, 1901 ~ 2100 年之间正确 + */ + static final long[] lunarInfo = + new long[]{ + 0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, + 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, + 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, + 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, + 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, + 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0, + 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, + 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, + 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, + 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, + 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, + 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, + 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, + 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, + 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0 + }; + + /** + * 中文日期格式 + */ + static final SimpleDateFormat chineseDateFormat = new SimpleDateFormat("yyyy年MM月dd日"); + + private final int year; // 农历年 + + // 上面4个值在构造方法中根据传入日期计算所得 + private final int month; // 农历月 + + private final int day; // 农历日 + + private boolean leap; // 农历闰年 + + /** + * 构造一个表示当前日期的农历日历 + */ + public LunarCalendar() { + this(Calendar.getInstance()); + } + + /** + * 构造一个表示指定日期的农历日历 + */ + public LunarCalendar(Date date) { + this(date2calendar(date)); + } + + /** + * 使用指定日历日期构造一个农历日历 + * + * @param cal 要构造的日历日期 + */ + public LunarCalendar(Calendar cal) { + @SuppressWarnings("unused") + int yearCyl, monCyl, dayCyl; + int leapMonth = 0; + Date baseDate = null; + try { + baseDate = chineseDateFormat.parse("1900年1月31日"); + } catch (ParseException e) { + } + + // 求出和1900年1月31日相差的天数 + int offset = (int) ((cal.getTime().getTime() - baseDate.getTime()) / 86400000L); + dayCyl = offset + 40; + monCyl = 14; + + // 用offset减去每农历年的天数 + // 计算当天是农历第几天 + // i最终结果是农历的年份 + // offset是当年的第几天 + int iYear, daysOfYear = 0; + for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) { + daysOfYear = yearDays(iYear); + offset -= daysOfYear; + monCyl += 12; + } + if (offset < 0) { + offset += daysOfYear; + iYear--; + monCyl -= 12; + } + // 农历年份 + year = iYear; + + yearCyl = iYear - 1864; + leapMonth = leapMonth(iYear); // 闰哪个月,1-12 + leap = false; + + // 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天 + int iMonth, daysOfMonth = 0; + for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) { + // 闰月 + if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) { + --iMonth; + leap = true; + daysOfMonth = leapDays(year); + } else { + daysOfMonth = monthDays(year, iMonth); + } + + offset -= daysOfMonth; + // 解除闰月 + if (leap && iMonth == (leapMonth + 1)) { + leap = false; + } + if (!leap) { + monCyl++; + } + } + // offset为0时,并且刚才计算的月份是闰月,要校正 + if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) { + if (leap) { + leap = false; + } else { + leap = true; + --iMonth; + --monCyl; + } + } + // offset小于0时,也要校正 + if (offset < 0) { + offset += daysOfMonth; + --iMonth; + --monCyl; + } + month = iMonth; + day = offset + 1; + } + + // ====== 传回农历 y年的总天数 + private static int yearDays(int y) { + int i, sum = 348; + for (i = 0x8000; i > 0x8; i >>= 1) { + if ((lunarInfo[y - 1900] & i) != 0) { + sum += 1; + } + } + return (sum + leapDays(y)); + } + + // ====== 传回农历 y年闰月的天数 + private static int leapDays(int y) { + if (leapMonth(y) != 0) { + if ((lunarInfo[y - 1900] & 0x10000) != 0) { + return 30; + } else { + return 29; + } + } else { + return 0; + } + } + + // ====== 传回农历 y年闰哪个月 1-12 , 没闰传回 0 + private static int leapMonth(int y) { + return (int) (lunarInfo[y - 1900] & 0xf); + } + + // ====== 传回农历 y年m月的总天数 + private static int monthDays(int y, int m) { + if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0) { + return 29; + } else { + return 30; + } + } + + private static Calendar date2calendar(Date date) { + Calendar tmpCale = Calendar.getInstance(); + tmpCale.setTime(date); + return tmpCale; + } + + // ====== 传回农历 y年的生肖 + public final String animalsYear() { + final String[] Animals = + new String[]{"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"}; + return Animals[(year - 4) % 12]; + } + + // ====== 传入 offset 传回干支, 0=甲子 + public final String cyclical() { + int num = year - 1900 + 36; + return (cyclicalm(num)); + } + + // ====== 传入 月日的offset 传回干支, 0=甲子 + private static String cyclicalm(int num) { + final String[] Gan = new String[]{"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"}; + final String[] Zhi = new String[]{"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"}; + return (Gan[num % 10] + Zhi[num % 12]); + } + + /** + * 获得表示农历年月日的日期对象 + * + * @return 表示日期的对象 + */ + public Date getDate() { + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.YEAR, year); + calendar.set(Calendar.MONTH, month - 1); + calendar.set(Calendar.DAY_OF_MONTH, day); + return calendar.getTime(); + } + + public String toString() { + return year + "年" + (leap ? "闰" : "") + chineseNumber[month - 1] + "月" + getChinaDayString(day); + } + + public static String getChinaDayString(int day) { + String[] chineseTen = {"初", "十", "廿", "卅"}; + int n = day % 10 == 0 ? 9 : day % 10 - 1; + if (day > 30) { + return ""; + } + if (day == 10) { + return "初十"; + } else { + return chineseTen[day / 10] + chineseNumber[n]; + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/IncompatibleChecker.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/IncompatibleChecker.java new file mode 100644 index 0000000..f3e77f1 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/IncompatibleChecker.java @@ -0,0 +1,97 @@ +/* + * This file is a part of project QuickShop, the name is IncompatibleChecker.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import java.util.HashSet; +import java.util.Set; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +public class IncompatibleChecker { + private Set incompatibleVersionList; + + public IncompatibleChecker() { + incompatibleVersionList = new HashSet<>(); + mc1_5(); + mc1_6(); + mc1_7(); + mc1_8(); + mc1_9(); + mc1_10(); + mc1_11(); + mc1_12(); + mc1_13(); + } + + private void mc1_5() { + incompatibleVersionList.add("v1_5_R1"); + incompatibleVersionList.add("v1_5_R2"); + incompatibleVersionList.add("v1_5_R3"); + } + + private void mc1_6() { + incompatibleVersionList.add("v1_6_R1"); + incompatibleVersionList.add("v1_6_R2"); + incompatibleVersionList.add("v1_6_R3"); + } + + private void mc1_7() { + incompatibleVersionList.add("v1_7_R1"); + incompatibleVersionList.add("v1_7_R2"); + incompatibleVersionList.add("v1_7_R3"); + incompatibleVersionList.add("v1_7_R4"); + } + + private void mc1_8() { + incompatibleVersionList.add("v1_8_R1"); + incompatibleVersionList.add("v1_8_R2"); + incompatibleVersionList.add("v1_8_R3"); + } + + private void mc1_9() { + incompatibleVersionList.add("v1_9_R1"); + incompatibleVersionList.add("v1_9_R2"); + } + + private void mc1_10() { + incompatibleVersionList.add("v1_10_R1"); + } + + private void mc1_11() { + incompatibleVersionList.add("v1_11_R1"); + } + + private void mc1_12() { + incompatibleVersionList.add("v1_12_R1"); + } + + private void mc1_13() { + incompatibleVersionList.add("v1_13_R1"); // 1.13.0-1.13.1 no Tag feature. + } + + public boolean isIncompatible(String version) { + return incompatibleVersionList.contains(version); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/IntegrationHelper.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/IntegrationHelper.java new file mode 100644 index 0000000..5d1a571 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/IntegrationHelper.java @@ -0,0 +1,127 @@ +/* + * This file is a part of project QuickShop, the name is IntegrationHelper.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import java.util.HashSet; +import java.util.Set; +import lombok.Getter; +import org.abc.A.I.IntegrateStage; +import org.abc.A.I.IntegratedPlugin; +import org.abc.A.I.IntegrationStage; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +@Getter +public class IntegrationHelper { + private Set integrations = new HashSet<>(); + + public void register(@NotNull IntegratedPlugin clazz) { + if (!isIntegrationClass(clazz)) { + throw new InvaildIntegratedPluginClass("Invaild Integration module: " + clazz.getName()); + } + Util.debugLog("Registering " + clazz.getName()); + integrations.add(clazz); + } + + private boolean isIntegrationClass(@NotNull IntegratedPlugin clazz) { + return clazz.getClass().getDeclaredAnnotation(IntegrationStage.class) != null; + } + + public void unregister(@NotNull IntegratedPlugin clazz) { + if (!isIntegrationClass(clazz)) { + throw new InvaildIntegratedPluginClass(); + } + Util.debugLog("Unregistering " + clazz.getName()); + integrations.remove(clazz); + } + + public void callIntegrationsLoad(@NotNull IntegrateStage stage) { + integrations.forEach( + integratedPlugin -> { + if (integratedPlugin.getClass().getDeclaredAnnotation(IntegrationStage.class).loadStage() + == stage) { + Util.debugLog("Calling for load " + integratedPlugin.getName()); + integratedPlugin.load(); + } else { + Util.debugLog( + "Ignored calling because " + + integratedPlugin.getName() + + " stage is " + + integratedPlugin + .getClass() + .getDeclaredAnnotation(IntegrationStage.class) + .loadStage()); + } + }); + } + + public void callIntegrationsUnload(@NotNull IntegrateStage stage) { + integrations.forEach( + integratedPlugin -> { + if (integratedPlugin.getClass().getDeclaredAnnotation(IntegrationStage.class).unloadStage() + == stage) { + Util.debugLog("Calling for unload " + integratedPlugin.getName()); + integratedPlugin.unload(); + } else { + Util.debugLog( + "Ignored calling because " + + integratedPlugin.getName() + + " stage is " + + integratedPlugin + .getClass() + .getDeclaredAnnotation(IntegrationStage.class) + .loadStage()); + } + }); + } + + public boolean callIntegrationsCanCreate(@NotNull Player player, @NotNull Location location) { + for (IntegratedPlugin plugin : integrations) { + if (!plugin.canCreateShopHere(player, location)) { + Util.debugLog("Cancelled by " + plugin.getName()); + return false; + } + } + return true; + } + + public boolean callIntegrationsCanTrade(@NotNull Player player, @NotNull Location location) { + for (IntegratedPlugin plugin : integrations) { + if (!plugin.canTradeShopHere(player, location)) { + Util.debugLog("Cancelled by " + plugin.getName()); + return false; + } + } + return true; + } + +} + +class InvaildIntegratedPluginClass extends IllegalArgumentException { + public InvaildIntegratedPluginClass() { + super(); + } + + public InvaildIntegratedPluginClass(String s) { + super(s); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/ItemNMS.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/ItemNMS.java new file mode 100644 index 0000000..ad3b7c5 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/ItemNMS.java @@ -0,0 +1,83 @@ +/* + * This file is a part of project QuickShop, the name is ItemNMS.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import java.lang.reflect.Method; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.QuickShop; + +@Getter +public abstract class ItemNMS { + private static Method craftItemStack_asNMSCopyMethod; + + private static Method itemStack_saveMethod; + + private static Class nbtTagCompoundClass; + + static { + String name = Bukkit.getServer().getClass().getPackage().getName(); + String nmsVersion = name.substring(name.lastIndexOf('.') + 1); + + try { + craftItemStack_asNMSCopyMethod = + Class.forName("org.bukkit.craftbukkit." + nmsVersion + ".inventory.CraftItemStack") + .getDeclaredMethod("asNMSCopy", ItemStack.class); + + nbtTagCompoundClass = Class.forName("net.minecraft.server." + nmsVersion + ".NBTTagCompound"); + + itemStack_saveMethod = + Class.forName("net.minecraft.server." + nmsVersion + ".ItemStack") + .getDeclaredMethod("save", nbtTagCompoundClass); + + } catch (Throwable t) { + QuickShop.instance.getLogger().info("A error happend:"); + t.printStackTrace(); + QuickShop.instance + .getLogger() + .info( + "Try to update QSRR and leave feedback about the bug on issue tracker if it continues."); + } + } + + /** + * Save ItemStack to Json passthrough the NMS. + * + * @param bStack ItemStack + * @return The json for ItemStack. + * @throws Throwable throws + */ + @Nullable + public static String saveJsonfromNMS(@NotNull ItemStack bStack) throws Throwable { + if (bStack.getType() == Material.AIR) { + return null; + } + Object mcStack = craftItemStack_asNMSCopyMethod.invoke(null, bStack); + Object nbtTagCompound = nbtTagCompoundClass.newInstance(); + + itemStack_saveMethod.invoke(mcStack, nbtTagCompound); + return nbtTagCompound.toString(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/BukkitGameLanguageImpl.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/BukkitGameLanguageImpl.java new file mode 100644 index 0000000..c9ab859 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/BukkitGameLanguageImpl.java @@ -0,0 +1,57 @@ +package org.abc.A.util.Language.Game; + +import org.abc.A.QuickShop; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.bukkit.potion.PotionEffectType; +import org.jetbrains.annotations.NotNull; + +public class BukkitGameLanguageImpl extends InternalGameLanguageImpl implements GameLanguage { + private QuickShop plugin; + + public BukkitGameLanguageImpl(@NotNull QuickShop plugin) { + super(plugin); + this.plugin = plugin; + } + + @Override + public @NotNull String getName() { + return "Bukkit"; + } + + @Override + public @NotNull Plugin getPlugin() { + return plugin; + } + + @Override + public @NotNull String getItem(@NotNull ItemStack itemStack) { + if(itemStack.getItemMeta() == null){ + return super.getItem(itemStack); + } + return itemStack.getItemMeta().getLocalizedName(); + } + + @Override + public @NotNull String getItem(@NotNull Material material) { + return super.getItem(material); + } + + @Override + public @NotNull String getPotion(@NotNull PotionEffectType potionEffectType) { + return super.getPotion(potionEffectType); + } + + @Override + public @NotNull String getEnchantment(@NotNull Enchantment enchantment) { + return super.getEnchantment(enchantment); + } + + @Override + public @NotNull String getEntity(@NotNull EntityType entityType) { + return super.getEntity(entityType); + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/GameLanguage.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/GameLanguage.java new file mode 100644 index 0000000..640988e --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/GameLanguage.java @@ -0,0 +1,19 @@ +package org.abc.A.util.Language.Game; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.bukkit.potion.PotionEffectType; +import org.jetbrains.annotations.NotNull; + +public interface GameLanguage { + @NotNull String getName(); + @NotNull Plugin getPlugin(); + @NotNull String getItem(@NotNull ItemStack itemStack); + @NotNull String getItem(@NotNull Material material); + @NotNull String getPotion(@NotNull PotionEffectType potionEffectType); + @NotNull String getEnchantment(@NotNull Enchantment enchantment); + @NotNull String getEntity(@NotNull EntityType entityType); +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/InternalGameLanguageImpl.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/InternalGameLanguageImpl.java new file mode 100644 index 0000000..effc18e --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/InternalGameLanguageImpl.java @@ -0,0 +1,51 @@ +package org.abc.A.util.Language.Game; + +import lombok.AllArgsConstructor; +import org.abc.A.QuickShop; +import org.abc.A.util.Util; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.bukkit.potion.PotionEffectType; +import org.jetbrains.annotations.NotNull; + +@AllArgsConstructor +public class InternalGameLanguageImpl implements GameLanguage{ + private QuickShop plugin; + @Override + public @NotNull String getName() { + return plugin.getName(); + } + + @Override + public @NotNull Plugin getPlugin() { + return plugin; + } + + @Override + public @NotNull String getItem(@NotNull ItemStack itemStack) { + return Util.prettifyText(itemStack.getType().name()); + } + + @Override + public @NotNull String getItem(@NotNull Material material) { + return Util.prettifyText(material.name()); + } + + @Override + public @NotNull String getPotion(@NotNull PotionEffectType potionEffectType) { + return Util.prettifyText(potionEffectType.getName()); + } + + @Override + public @NotNull String getEnchantment(@NotNull Enchantment enchantment) { + return Util.prettifyText(enchantment.getKey().getKey()); + } + + @Override + public @NotNull String getEntity(@NotNull EntityType entityType) { + return Util.prettifyText(entityType.name()); + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/MojangGameLanguageImpl.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/MojangGameLanguageImpl.java new file mode 100644 index 0000000..981ad9f --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Language/Game/MojangGameLanguageImpl.java @@ -0,0 +1,266 @@ +package org.abc.A.util.Language.Game; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import lombok.Getter; +import lombok.Setter; +import lombok.SneakyThrows; +import org.abc.A.QuickShop; +import org.abc.A.util.Copied; +import org.abc.A.util.ReflectFactory; +import org.abc.A.util.Util; +import org.abc.A.util.mojangapi.AssetJson; +import org.abc.A.util.mojangapi.MojangAPI; +import org.bukkit.Material; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.bukkit.potion.PotionEffectType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.nio.charset.StandardCharsets; +import java.util.Locale; +import java.util.Objects; + + public class MojangGameLanguageImpl extends BukkitGameLanguageImpl implements GameLanguage { + private QuickShop plugin; + private @Nullable JsonObject lang; + @SneakyThrows + public MojangGameLanguageImpl(@NotNull QuickShop plugin, @NotNull String languageCode) { + super(plugin); + this.plugin = plugin; + final GameLanguageLoadThread loadThread = new GameLanguageLoadThread(); + languageCode = languageCode.replace("-", "_"); + loadThread.setLanguageCode(languageCode); + loadThread.setMainThreadWaiting(true); // Told thread we're waiting him + loadThread.start(); + int count = 0; + while (count < 7) { + if (loadThread.isAlive()) { + count++; + Thread.sleep(1000); + if (count >= 20) { + Util.debugLog( + "No longer waiting file downloading because it now timed out, now downloading in background."); + QuickShop.instance + .getLogger() + .info( + "No longer waiting file downloading because it now timed out, now downloading in background, please reset itemi18n.yml, potioni18n.yml and enchi18n.yml after download completed."); + } + } else { + break; + } + } + this.lang = loadThread.getLang(); // Get the Lang whatever thread running or died. + loadThread.setMainThreadWaiting( + false); // Told thread it now move to background, thread should told user reset files. + + } + + @Override + public @NotNull String getName() { + return "Mojang API"; + } + + @Override + public @NotNull Plugin getPlugin() { + return plugin; + } + + @Override + public @NotNull String getItem(@NotNull ItemStack itemStack) { + return getItem(itemStack.getType()); + } + + @Override + public @NotNull String getItem(@NotNull Material material) { + try { + JsonElement element = Objects.requireNonNull(lang).get("item.minecraft." + material.name().toLowerCase()); + if (element == null) { + return getBlock(material); + } else { + return element.getAsString(); + } + } catch (NullPointerException npe) { + return super.getItem(material); + } + } + + /** + * Get block only translations, if not found, it WON'T call getItem() + * + * @param material The material + * @return The translations for material + */ + @NotNull + public String getBlock(@NotNull Material material) { + if (lang == null) { + return super.getItem(material); + } + try { + return lang.get("block.minecraft." + material.name().toLowerCase()).getAsString(); + } catch (NullPointerException e) { + return super.getItem(material); + } + } + + @Override + public @NotNull String getPotion(@NotNull PotionEffectType potionEffectType) { + if (lang == null) { + return super.getPotion(potionEffectType); + } + try { + return lang.get("effect.minecraft." + potionEffectType.getName().toLowerCase()).getAsString(); + } catch (NullPointerException e) { + return super.getPotion(potionEffectType); + } + } + + @Override + public @NotNull String getEnchantment(@NotNull Enchantment enchantment) { + if (lang == null) { + return super.getEnchantment(enchantment); + } + try { + return lang.get("enchantment.minecraft." + enchantment.getKey().getKey().toLowerCase()).getAsString(); + } catch (NullPointerException e) { + return super.getEnchantment(enchantment); + } + } + + @Override + public @NotNull String getEntity(@NotNull EntityType entityType) { + if (lang == null) { + return super.getEntity(entityType); + } + try { + return lang.get("entity.minecraft." + entityType.name().toLowerCase()).getAsString(); + } catch (NullPointerException e) { + return super.getEntity(entityType); + } + } +} + +@Getter +@Setter +class GameLanguageLoadThread extends Thread { + private JsonObject lang; + + private String languageCode; + + private boolean mainThreadWaiting; + + public void run() { + boolean failed = false; + try { + File cacheFile = new File(Util.getCacheFolder(), "lang.cache"); // Load cache file + if (!cacheFile.exists()) { + //noinspection ResultOfMethodCallIgnored + cacheFile.createNewFile(); + } + YamlConfiguration yamlConfiguration = new YamlConfiguration(); + yamlConfiguration.load(new File(Util.getCacheFolder(), "lang.cache")); + boolean needUpdateCache = false; + /* The cache data, if it all matches, we doesn't need connect to internet to download files again. */ + String cachingServerVersion = yamlConfiguration.getString("ver"); + String cachingLanguageHash = yamlConfiguration.getString("hash"); + String cachingLanguageName = yamlConfiguration.getString("lang"); + /* If language name is default, use computer language */ + if ("default".equals(languageCode)) { + Locale locale = Locale.getDefault(); + languageCode = locale.getLanguage() + "_" + locale.getCountry(); + } + if (!languageCode.equals(cachingLanguageName)) { + cachingLanguageName = languageCode; + needUpdateCache = true; + } + String languageCode1 = languageCode.toLowerCase(); + String serverVersion = ReflectFactory.getServerVersion(); + if (!serverVersion.equals(cachingServerVersion)) { + cachingServerVersion = serverVersion; + needUpdateCache = true; + } + if (cachingLanguageHash == null || cachingLanguageHash.isEmpty()) { + needUpdateCache = true; + } + if (needUpdateCache) { + MojangAPI mojangAPI = new MojangAPI(); + String assetJson = mojangAPI.getAssetIndexJson(cachingServerVersion); + if (assetJson != null) { + AssetJson versionJson = new AssetJson(assetJson); + String hash = versionJson.getLanguageHash(languageCode1); + if (hash != null) { + cachingLanguageHash = hash; + String langJson = mojangAPI.downloadTextFileFromMojang(hash); + if (langJson != null) { + new Copied(new File(Util.getCacheFolder(), hash)) + .accept(new ByteArrayInputStream(langJson.getBytes(StandardCharsets.UTF_8))); + } else { + Util.debugLog("Cannot download file."); + QuickShop.instance + .getLogger() + .warning( + "Cannot download require files, some items/blocks/potions/enchs language will use default English name."); + failed = true; + } + } else { + Util.debugLog("Cannot get file hash for language " + languageCode1); + QuickShop.instance + .getLogger() + .warning( + "Cannot download require files, some items/blocks/potions/enchs language will use default English name."); + failed = true; + } + } else { + Util.debugLog("Cannot get version json."); + QuickShop.instance + .getLogger() + .warning( + "Cannot download require files, some items/blocks/potions/enchs language will use default English name."); + failed = true; + } + } + yamlConfiguration.set("ver", cachingServerVersion); + yamlConfiguration.set("hash", cachingLanguageHash); + yamlConfiguration.set("lang", cachingLanguageName); + yamlConfiguration.save(cacheFile); + String json = null; + if (cachingLanguageHash != null) { + json = Util.readToString(new File(Util.getCacheFolder(), cachingLanguageHash)); + } else { + Util.debugLog("Caching LanguageHash is null"); + } + if (json != null && !json.isEmpty()) { + lang = new JsonParser().parse(json).getAsJsonObject(); + } else { + Util.debugLog("json is null"); + } + } catch (Exception e) { + QuickShop.instance.getSentryErrorReporter().ignoreThrow(); + e.printStackTrace(); + failed = true; + } + if (!this.mainThreadWaiting) { + + if (!failed) { + + QuickShop.instance + .getLogger() + .info( + "Download completed, please execute /qs reset lang to generate localized language files."); + } else { + QuickShop.instance + .getLogger() + .info( + "Failed to download required files, we will try again when plugin next loading."); + } + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/MsgUtil.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/MsgUtil.java new file mode 100644 index 0000000..95149e1 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/MsgUtil.java @@ -0,0 +1,1379 @@ +/* + * This file is a part of project QuickShop, the name is MsgUtil.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import lombok.SneakyThrows; +import me.clip.placeholderapi.PlaceholderAPI; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.H.old.IFile; +import org.abc.A.H.old.JSONFile; +import org.abc.A.QuickShop; +import org.abc.A.ServiceInjector; +import org.abc.A.N.Shop; +import org.abc.A.util.Language.Game.GameLanguage; +import org.abc.A.util.Language.Game.MojangGameLanguageImpl; + +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.DecimalFormat; +import java.util.*; +import java.util.Map.Entry; +import java.util.logging.Level; + + +public class MsgUtil { + private static final String invaildMsg = "Invaild message"; + + private static final HashMap> player_messages = new HashMap<>(); + + private static final QuickShop plugin = QuickShop.instance; + + private static final DecimalFormat decimalFormat = + new DecimalFormat(Objects.requireNonNull(plugin.getConfig().getString("decimal-format"))); + + private static YamlConfiguration enchi18n; + + private static boolean inited; + + private static YamlConfiguration itemi18n; + + private static IFile messagei18n; + + private static YamlConfiguration potioni18n; + + private static GameLanguage gameLanguage; + + private static IFile builtInLang; + + /** + * Deletes any messages that are older than a week in the database, to save on space. + */ + public static void clean() { + plugin + .getLogger() + .info("Cleaning purchase messages from the database that are over a week old..."); + // 604800,000 msec = 1 week. + plugin.getDatabaseHelper().cleanMessage(System.currentTimeMillis() - 604800000); + } + + /** + * Empties the queue of messages a player has and sends them to the player. + * + * @param p The player to message + * @return True if success, False if the player is offline or null + */ + public static boolean flush(@NotNull OfflinePlayer p) { + Player player = p.getPlayer(); + if (player != null) { + UUID pName = p.getUniqueId(); + LinkedList msgs = player_messages.get(pName); + if (msgs != null) { + for (String msg : msgs) { + if (p.getPlayer() != null) { + Util.debugLog("Accepted the msg for player " + p.getName() + " : " + msg); + String[] msgData = msg.split("##########"); + try { + ItemStack data = Util.deserialize(msgData[1]); + if (data == null) { + throw new InvalidConfigurationException(); + } + sendItemholochat(player, msgData[0], data, msgData[2]); + } catch (InvalidConfigurationException e) { + MsgUtil.sendMessage(p.getPlayer(),msgData[0] + msgData[1] + msgData[2]); + } catch (ArrayIndexOutOfBoundsException e2) { + MsgUtil.sendMessage(p.getPlayer(),msg); + } + } + } + plugin.getDatabaseHelper().cleanMessageForPlayer(pName); + msgs.clear(); + return true; + } + } + return false; + } + + @SneakyThrows + public static void sendItemholochat( + @NotNull Player player, + @NotNull String left, + @NotNull ItemStack itemStack, + @NotNull String right) { + String json = ItemNMS.saveJsonfromNMS(itemStack); + if (json == null) { + return; + } + Util.debugLog(left); + Util.debugLog(itemStack.toString()); + Util.debugLog(right); + TextComponent centerItem = new TextComponent(left + Util.getItemStackName(itemStack) + right); + ComponentBuilder cBuilder = new ComponentBuilder(json); + centerItem.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, cBuilder.create())); + player.spigot().sendMessage(centerItem); + } + + /** + * Get item's i18n name, If you want get item name, use Util.getItemStackName + * + * @param itemBukkitName ItemBukkitName(e.g. Material.STONE.name()) + * @return String Item's i18n name. + */ + public static String getItemi18n(@NotNull String itemBukkitName) { + if (itemBukkitName.isEmpty()) { + return "Item is empty"; + } + String itemnameI18n = itemi18n.getString("itemi18n." + itemBukkitName); + if (itemnameI18n != null && !itemnameI18n.isEmpty()) { + return itemnameI18n; + } + Material material = Material.matchMaterial(itemBukkitName); + if (material == null) { + return "Material not exist"; + } + return Util.prettifyText(material.name()); + } + + /** + * getMessage in messages.yml + * + * @param loc location + * @param player The sender will send the message to + * @param args args + * @return message + */ + public static String getMessageOfflinePlayer( + @NotNull String loc, @Nullable OfflinePlayer player, @NotNull String... args) { + try { + Optional raw = messagei18n.getString(loc); + if (!raw.isPresent()) { + return invaildMsg + ": " + loc; + } + String filled = fillArgs(raw.get(), args); + if (player != null) { + if (plugin.getPlaceHolderAPI() != null && plugin.getPlaceHolderAPI().isEnabled()) { + filled = PlaceholderAPI.setPlaceholders(player, filled); + Util.debugLog("Processed message " + filled + " by PlaceHolderAPI."); + } + } + return filled; + } catch (Throwable th) { + plugin.getSentryErrorReporter().ignoreThrow(); + th.printStackTrace(); + return "Cannot load language key: " + loc + " because something not right, check the console for details."; + } + } + + /** + * Replace args in raw to args + * + * @param raw text + * @param args args + * @return filled text + */ + public static String fillArgs(@Nullable String raw, @Nullable String... args) { + if (raw == null) { + return "Invalid message: null"; + } + if (raw.isEmpty()) { + return ""; + } + if (args == null) { + return raw; + } + for (int i = 0; i < args.length; i++) { + raw = StringUtils.replace(raw, "{" + i + "}", args[i] == null ? "" : args[i]); + } + return raw; + } + + public static void loadGameLanguage(@NotNull String languageCode) { + gameLanguage = ServiceInjector.getGameLanguage(new MojangGameLanguageImpl(plugin, languageCode)); + } + + public static void loadCfgMessages() throws InvalidConfigurationException { + plugin.getLogger().info("Loading plugin translations files..."); + /* Check & Load & Create default messages.yml */ + // Use try block to hook any possible exception, make sure not effect our cfgMessnages code. + String languageCode = plugin.getConfig().getString("language", "en-US"); + languageCode = languageCode.replace("_", "-"); + //noinspection ConstantConditions + + loadGameLanguage(plugin.getConfig().getString("game-language", "default")); + // Init nJson + IFile nJson; + if (plugin.getResource("lang/" + languageCode + "/messages.json") == null) { + nJson = + new JSONFile( + plugin, new File(plugin.getDataFolder(), "messages.json"), "lang-original/messages.json", true); + } else { + nJson = + new JSONFile( + plugin, + new File(plugin.getDataFolder(), "messages.json"), + "lang/" + languageCode + "/messages.json", + true); + } + nJson.create(); + + File oldMsgFile = new File(plugin.getDataFolder(), "messages.yml"); + if (oldMsgFile.exists()) { // Old messages file convert. + plugin.getLogger().info("Converting the old format message.yml to message.json..."); + plugin.getLanguage().saveFile(languageCode, "messages", "messages.json"); + YamlConfiguration oldMsgI18n = YamlConfiguration.loadConfiguration(oldMsgFile); + for (String key : oldMsgI18n.getKeys(true)) { + nJson.set(key, oldMsgI18n.get(key)); + } + nJson.save(); + try { + Files.move( + oldMsgFile.toPath(), new File(plugin.getDataFolder(), "messages.yml.bak").toPath()); + } catch (IOException ignore) { + } + if (oldMsgFile.exists()) { + oldMsgFile.delete(); + } + plugin.getLogger().info("Successfully converted, Continue loading..."); + } else { + Util.debugLog("Loading language file from exist file..."); + if (!new File(plugin.getDataFolder(), "messages.json").exists()) { + plugin.getLanguage().saveFile(languageCode, "messages", "messages.json"); + nJson.loadFromString(Util.readToString(new File(plugin.getDataFolder(), "messages.json").getAbsolutePath())); + nJson.set("language-name", languageCode); + } + } + messagei18n = nJson; + /* Set default language vesion and update messages.yml */ + Optional ver = messagei18n.getString("language-version"); + int versi = 0; + if (ver.isPresent()) { + String vers = ver.get(); + try { + versi = Integer.parseInt(vers); + } catch (NumberFormatException ignore) { + + } + } + if (messagei18n.getInt("language-version") == 0 && versi == 0) { + messagei18n.set("language-version", 1); + } else { + messagei18n.set("language-version", versi); + } + updateMessages(messagei18n.getInt("language-version")); + messagei18n.loadFromString(Util.parseColours(messagei18n.saveToString())); + + /* Print to console this language file's author, contributors, and region*/ + if (!inited) { + plugin.getLogger().info(getMessage("translation-author", null)); + plugin.getLogger().info(getMessage("translation-contributors", null)); + plugin.getLogger().info(getMessage("translation-country", null)); + // plugin.getLogger().info(getMessage("translation-version")); + inited = true; + } + /* Save the upgraded messages.yml */ + plugin.getLogger().info("Completed to load plugin translations files."); + } + + public static void loadEnchi18n() { + plugin.getLogger().info("Starting loading enchantments translation..."); + File enchi18nFile = new File(plugin.getDataFolder(), "enchi18n.yml"); + if (!enchi18nFile.exists()) { + plugin.getLogger().info("Creating enchi18n.yml"); + plugin.saveResource("enchi18n.yml", false); + } + // Store it + enchi18n = YamlConfiguration.loadConfiguration(enchi18nFile); + enchi18n.options().copyDefaults(false); + YamlConfiguration enchi18nYAML = + YamlConfiguration.loadConfiguration( + new InputStreamReader(Objects.requireNonNull(plugin.getResource("enchi18n.yml")))); + enchi18n.setDefaults(enchi18nYAML); + Util.parseColours(enchi18n); + Enchantment[] enchsi18n = Enchantment.values(); + for (Enchantment ench : enchsi18n) { + String enchi18nString = enchi18n.getString("enchi18n." + ench.getKey().getKey().trim()); + if (enchi18nString != null && !enchi18nString.isEmpty()) { + continue; + } + String enchName = gameLanguage.getEnchantment(ench); + enchi18n.set("enchi18n." + ench.getKey().getKey(), enchName); + plugin.getLogger().info("Found new ench [" + enchName + "] , adding it to the config..."); + } + try { + enchi18n.save(enchi18nFile); + } catch (IOException e) { + e.printStackTrace(); + plugin + .getLogger() + .log( + Level.WARNING, + "Could not load/save transaction enchname from enchi18n.yml. Skipping."); + } + plugin.getLogger().info("Complete to load enchantments translation."); + } + + /** + * Load Itemi18n fron file + */ + public static void loadItemi18n() { + plugin.getLogger().info("Starting loading items translation..."); + File itemi18nFile = new File(plugin.getDataFolder(), "itemi18n.yml"); + if (!itemi18nFile.exists()) { + plugin.getLogger().info("Creating itemi18n.yml"); + plugin.saveResource("itemi18n.yml", false); + } + // Store it + itemi18n = YamlConfiguration.loadConfiguration(itemi18nFile); + itemi18n.options().copyDefaults(false); + YamlConfiguration itemi18nYAML = + YamlConfiguration.loadConfiguration( + new InputStreamReader(Objects.requireNonNull(plugin.getResource("itemi18n.yml")))); + itemi18n.setDefaults(itemi18nYAML); + Util.parseColours(itemi18n); + Material[] itemsi18n = Material.values(); + for (Material material : itemsi18n) { + String itemi18nString = itemi18n.getString("itemi18n." + material.name()); + if (itemi18nString != null && !itemi18nString.isEmpty()) { + continue; + } + String itemName = gameLanguage.getItem(material); + itemi18n.set("itemi18n." + material.name(), itemName); + plugin + .getLogger() + .info("Found new items/blocks [" + itemName + "] , adding it to the config..."); + } + try { + itemi18n.save(itemi18nFile); + } catch (IOException e) { + e.printStackTrace(); + plugin + .getLogger() + .log( + Level.WARNING, + "Could not load/save transaction itemname from itemi18n.yml. Skipping."); + } + plugin.getLogger().info("Complete to load items translation."); + } + + public static void loadPotioni18n() { + plugin.getLogger().info("Starting loading potions translation..."); + File potioni18nFile = new File(plugin.getDataFolder(), "potioni18n.yml"); + if (!potioni18nFile.exists()) { + plugin.getLogger().info("Creating potioni18n.yml"); + plugin.saveResource("potioni18n.yml", false); + } + // Store it + potioni18n = YamlConfiguration.loadConfiguration(potioni18nFile); + potioni18n.options().copyDefaults(false); + YamlConfiguration potioni18nYAML = + YamlConfiguration.loadConfiguration( + new InputStreamReader(Objects.requireNonNull(plugin.getResource("potioni18n.yml")))); + potioni18n.setDefaults(potioni18nYAML); + Util.parseColours(potioni18n); + for (PotionEffectType potion : PotionEffectType.values()) { + String potionI18n = potioni18n.getString("potioni18n." + potion.getName().trim()); + if (potionI18n != null && !potionI18n.isEmpty()) { + continue; + } + String potionName = gameLanguage.getPotion(potion); + plugin.getLogger().info("Found new potion [" + potionName + "] , adding it to the config..."); + potioni18n.set("potioni18n." + potion.getName(), potionName); + } + try { + potioni18n.save(potioni18nFile); + } catch (IOException e) { + e.printStackTrace(); + plugin + .getLogger() + .log( + Level.WARNING, + "Could not load/save transaction potionname from potioni18n.yml. Skipping."); + } + plugin.getLogger().info("Complete to load potions effect translation."); + } + + /** + * loads all player purchase messages from the database. + */ + public static void loadTransactionMessages() { + player_messages.clear(); // Delete old messages + try { + ResultSet rs = plugin.getDatabaseHelper().selectAllMessages(); + while (rs.next()) { + String owner = rs.getString("owner"); + UUID ownerUUID; + if (Util.isUUID(owner)) { + ownerUUID = UUID.fromString(owner); + } else { + ownerUUID = Bukkit.getOfflinePlayer(owner).getUniqueId(); + } + String message = rs.getString("message"); + LinkedList msgs = + player_messages.computeIfAbsent(ownerUUID, k -> new LinkedList<>()); + msgs.add(message); + } + } catch (SQLException e) { + e.printStackTrace(); + plugin + .getLogger() + .log(Level.WARNING, "Could not load transaction messages from database. Skipping."); + } + } + + /** + * @param player The name of the player to message + * @param message The message to send them Sends the given player a message if they're online. + * Else, if they're not online, queues it for them in the database. + * @param isUnlimited The shop is or unlimited + */ + public static void send(@NotNull UUID player, @NotNull String message, boolean isUnlimited) { + if (plugin.getConfig().getBoolean("shop.ignore-unlimited-shop-messages") && isUnlimited) { + return; // Ignore unlimited shops messages. + } + Util.debugLog(message); + String[] msgData = message.split("##########"); + OfflinePlayer p = Bukkit.getOfflinePlayer(player); + if (!p.isOnline()) { + LinkedList msgs = player_messages.get(player); + if (msgs == null) { + msgs = new LinkedList<>(); + } + player_messages.put(player, msgs); + msgs.add(message); + plugin.getDatabaseHelper().sendMessage(player, message, System.currentTimeMillis()); + } else { + if (p.getPlayer() != null) { + try { + sendItemholochat(p.getPlayer(), msgData[0], Util.deserialize(msgData[1]), msgData[2]); + } catch (InvalidConfigurationException e) { + Util.debugLog("Unknown error, send by plain text."); + p.getPlayer().sendMessage(msgData[0] + msgData[1] + msgData[2]); + } catch (ArrayIndexOutOfBoundsException e2) { + try { + sendItemholochat(p.getPlayer(), msgData[0], Util.deserialize(msgData[1]), ""); + } catch (Exception any) { + // Normal msg + p.getPlayer().sendMessage(message); + } + } + } + } + } + + public static @NotNull String getSubString( + @NotNull String text, @NotNull String left, @NotNull String right) { + String result; + int zLen; + if (left.isEmpty()) { + zLen = 0; + } else { + zLen = text.indexOf(left); + if (zLen > -1) { + zLen += left.length(); + } else { + zLen = 0; + } + } + int yLen = text.indexOf(right, zLen); + if (yLen < 0 || right.isEmpty()) { + yLen = text.length(); + } + result = text.substring(zLen, yLen); + return result; + } + + /** + * Send controlPanel infomation to sender + * + * @param sender Target sender + * @param shop Target shop + */ + public static void sendControlPanelInfo(@NotNull CommandSender sender, @NotNull Shop shop) { + if ((sender instanceof Player && !sender.isOp()) + && !QuickShop.getPermissionManager().hasPermission(sender, "quickshop.use")) { + return; + } + if (plugin.getConfig().getBoolean("sneak-to-control")) { + if (sender instanceof Player) { + if (!((Player) sender).isSneaking()) { // sneaking + return; + } + } + } + ChatSheetPrinter chatSheetPrinter = new ChatSheetPrinter(sender); + chatSheetPrinter.printHeader(); + chatSheetPrinter.printLine(MsgUtil.getMessage("controlpanel.infomation", sender)); + // Owner + if (!QuickShop.getPermissionManager().hasPermission(sender, "quickshop.setowner")) { + chatSheetPrinter.printLine(MsgUtil.getMessage("menu.owner", sender, shop.ownerName())); + } else { + chatSheetPrinter.printSuggestableCmdLine( + MsgUtil.getMessage( + "controlpanel.setowner", + sender, + shop.ownerName() + + ((plugin.getConfig().getBoolean("shop.show-owner-uuid-in-controlpanel-if-op") + && shop.isUnlimited()) + ? (" (" + shop.getOwner() + ")") + : "")), + MsgUtil.getMessage("controlpanel.setowner-hover", sender), + MsgUtil.getMessage("controlpanel.commands.setowner", sender)); + } + + // Unlimited + if (QuickShop.getPermissionManager().hasPermission(sender, "quickshop.unlimited")) { + String text = + MsgUtil.getMessage("controlpanel.unlimited", sender, bool2String(shop.isUnlimited())); + String hoverText = MsgUtil.getMessage("controlpanel.unlimited-hover", sender); + String clickCommand = + MsgUtil.getMessage( + "controlpanel.commands.unlimited", + sender, + Objects.requireNonNull(shop.getLocation().getWorld()).getName(), + String.valueOf(shop.getLocation().getBlockX()), + String.valueOf(shop.getLocation().getBlockY()), + String.valueOf(shop.getLocation().getBlockZ())); + chatSheetPrinter.printExecuteableCmdLine(text, hoverText, clickCommand); + } + // Buying/Selling Mode + if (QuickShop.getPermissionManager().hasPermission(sender, "quickshop.create.buy") + && sender.hasPermission("quickshop.create.sell")) { + if (shop.isSelling()) { + String text = MsgUtil.getMessage("controlpanel.mode-selling", sender); + String hoverText = MsgUtil.getMessage("controlpanel.mode-selling-hover", sender); + String clickCommand = + MsgUtil.getMessage( + "controlpanel.commands.buy", + sender, + Objects.requireNonNull(shop.getLocation().getWorld()).getName(), + String.valueOf(shop.getLocation().getBlockX()), + String.valueOf(shop.getLocation().getBlockY()), + String.valueOf(shop.getLocation().getBlockZ())); + chatSheetPrinter.printExecuteableCmdLine(text, hoverText, clickCommand); + } else if (shop.isBuying()) { + String text = MsgUtil.getMessage("controlpanel.mode-buying", sender); + String hoverText = MsgUtil.getMessage("controlpanel.mode-buying-hover", sender); + String clickCommand = + MsgUtil.getMessage( + "controlpanel.commands.sell", + sender, + Objects.requireNonNull(shop.getLocation().getWorld()).getName(), + String.valueOf(shop.getLocation().getBlockX()), + String.valueOf(shop.getLocation().getBlockY()), + String.valueOf(shop.getLocation().getBlockZ())); + chatSheetPrinter.printExecuteableCmdLine(text, hoverText, clickCommand); + } + } + // Set Price + if (QuickShop.getPermissionManager().hasPermission(sender, "quickshop.other.price") + || shop.getOwner().equals(((OfflinePlayer) sender).getUniqueId())) { + String text = + MsgUtil.getMessage( + "controlpanel.price", + sender, + (plugin.getConfig().getBoolean("use-decimal-format")) + ? decimalFormat(shop.getPrice()) + : "" + shop.getPrice()); + String hoverText = MsgUtil.getMessage("controlpanel.price-hover", sender); + String clickCommand = MsgUtil.getMessage("controlpanel.commands.price", sender); + chatSheetPrinter.printSuggestableCmdLine(text, hoverText, clickCommand); + } + // Refill + if (QuickShop.getPermissionManager().hasPermission(sender, "quickshop.refill")) { + String text = + MsgUtil.getMessage("controlpanel.refill", sender, String.valueOf(shop.getPrice())); + String hoverText = MsgUtil.getMessage("controlpanel.refill-hover", sender); + String clickCommand = MsgUtil.getMessage("controlpanel.commands.refill", sender); + chatSheetPrinter.printSuggestableCmdLine(text, hoverText, clickCommand); + } + // Refill + if (QuickShop.getPermissionManager().hasPermission(sender, "quickshop.empty")) { + String text = + MsgUtil.getMessage("controlpanel.empty", sender, String.valueOf(shop.getPrice())); + String hoverText = MsgUtil.getMessage("controlpanel.empty-hover", sender); + String clickCommand = + MsgUtil.getMessage( + "controlpanel.commands.empty", + sender, + Objects.requireNonNull(shop.getLocation().getWorld()).getName(), + String.valueOf(shop.getLocation().getBlockX()), + String.valueOf(shop.getLocation().getBlockY()), + String.valueOf(shop.getLocation().getBlockZ())); + chatSheetPrinter.printExecuteableCmdLine(text, hoverText, clickCommand); + } + // Remove + if (QuickShop.getPermissionManager().hasPermission(sender, "quickshop.other.destroy") + || shop.getOwner().equals(((OfflinePlayer) sender).getUniqueId())) { + String text = + MsgUtil.getMessage("controlpanel.remove", sender, String.valueOf(shop.getPrice())); + String hoverText = MsgUtil.getMessage("controlpanel.remove-hover", sender); + String clickCommand = + MsgUtil.getMessage( + "controlpanel.commands.remove", + sender, + Objects.requireNonNull(shop.getLocation().getWorld()).getName(), + String.valueOf(shop.getLocation().getBlockX()), + String.valueOf(shop.getLocation().getBlockY()), + String.valueOf(shop.getLocation().getBlockZ())); + chatSheetPrinter.printExecuteableCmdLine(text, hoverText, clickCommand); + } + + chatSheetPrinter.printFooter(); + } + + /** + * getMessage in messages.yml + * + * @param loc location + * @param args args + * @param player The sender will send the message to + * @return message + */ + public static String getMessage( + @NotNull String loc, @Nullable CommandSender player, @NotNull String... args) { + try { + Optional raw = messagei18n.getString(loc); + if (!raw.isPresent()) { + Util.debugLog("ERR: MsgUtil cannot find the the phrase at " + loc + ", printing the all readed datas: " + messagei18n); + + return invaildMsg + ": " + loc; + } + String filled = fillArgs(raw.get(), args); + if (player instanceof OfflinePlayer) { + if (plugin.getPlaceHolderAPI() != null && plugin.getPlaceHolderAPI().isEnabled()) { + try { + filled = PlaceholderAPI.setPlaceholders((OfflinePlayer) player, filled); + } catch (Exception ignored) { + if (((OfflinePlayer) player).getPlayer() != null) { + try { + filled = PlaceholderAPI.setPlaceholders(((OfflinePlayer) player).getPlayer(), filled); + } catch (Exception ignore) { + } + } + } + } + } + return filled; + } catch (Throwable th) { + plugin.getSentryErrorReporter().ignoreThrow(); + th.printStackTrace(); + return "Cannot load language key: " + loc + " because something not right, check the console for details."; + } + } + + /** + * Translate boolean value to String, the symbon is changeable by language file. + * + * @param bool The boolean value + * @return The result of translate. + */ + public static String bool2String(boolean bool) { + if (bool) { + return MsgUtil.getMessage("booleanformat.success", null); + } else { + return MsgUtil.getMessage("booleanformat.failed", null); + } + } + + public static String decimalFormat(double value) { + return decimalFormat.format(value); + } + + /** + * Send globalAlert to ops, console, log file. + * + * @param content The content to send. + */ + public static void sendGlobalAlert(@Nullable String content) { + if (content == null) { + Util.debugLog("Content is null"); + Throwable throwable = + new Throwable("Known issue: Global Alert accepted null string, what the fuck"); + plugin.getSentryErrorReporter().sendError(throwable, "NullCheck"); + return; + } + sendMessageToOps(content); + plugin.getLogger().warning(content); + Objects.requireNonNull(plugin.getLogWatcher()).add(content); + Util.debugLog(content); + } + + /** + * Send a message for all online Ops. + * + * @param message The message you want send + */ + public static void sendMessageToOps(@NotNull String message) { + new BukkitRunnable() { + @Override + public void run() { + for (Player player : Bukkit.getOnlinePlayers()) { + if (player.isOp() + || QuickShop.getPermissionManager().hasPermission(player, "quickshop.alert")) { + player.sendMessage(message); + } + } + } + }.runTaskAsynchronously(plugin); + } + + /** + * Send a purchaseSuccess message for a player. + * + * @param p Target player + * @param shop Target shop + * @param amount Trading item amounts. + */ + public static void sendPurchaseSuccess(@NotNull Player p, @NotNull Shop shop, int amount) { + ChatSheetPrinter chatSheetPrinter = new ChatSheetPrinter(p); + chatSheetPrinter.printHeader(); + chatSheetPrinter.printLine(MsgUtil.getMessage("menu.successful-purchase", p)); + chatSheetPrinter.printLine( + MsgUtil.getMessage( + "menu.item-name-and-price", + p, + "" + amount, + Util.getItemStackName(shop.getItem()), + Util.format((amount * shop.getPrice())))); + printEnchantment(p, shop, chatSheetPrinter); + chatSheetPrinter.printFooter(); + } + + /** + * Get Enchantment's i18n name. + * + * @param key The Enchantment. + * @return Enchantment's i18n name. + */ + public static String getEnchi18n(@NotNull Enchantment key) { + String enchString = key.getKey().getKey(); + if (enchString.isEmpty()) { + return "Enchantment key is empty"; + } + String enchI18n = enchi18n.getString("enchi18n." + enchString); + if (enchI18n != null && !enchI18n.isEmpty()) { + return enchI18n; + } + return Util.prettifyText(enchString); + } + + /** + * Send a sellSuccess message for a player. + * + * @param p Target player + * @param shop Target shop + * @param amount Trading item amounts. + */ + public static void sendSellSuccess(@NotNull Player p, @NotNull Shop shop, int amount) { + ChatSheetPrinter chatSheetPrinter = new ChatSheetPrinter(p); + chatSheetPrinter.printHeader(); + chatSheetPrinter.printLine(MsgUtil.getMessage("menu.successfully-sold", p)); + chatSheetPrinter.printLine( + MsgUtil.getMessage( + "menu.item-name-and-price", + p, + "" + amount, + Util.getItemStackName(shop.getItem()), + Util.format((amount * shop.getPrice())))); + if (plugin.getConfig().getBoolean("show-tax")) { + double tax = plugin.getConfig().getDouble("tax"); + double total = amount * shop.getPrice(); + if (tax != 0) { + if (!p.getUniqueId().equals(shop.getOwner())) { + chatSheetPrinter.printLine( + MsgUtil.getMessage("menu.sell-tax", p, Util.format((tax * total)))); + } else { + chatSheetPrinter.printLine(MsgUtil.getMessage("menu.sell-tax-self", p)); + } + } + } + printEnchantment(p, shop, chatSheetPrinter); + chatSheetPrinter.printFooter(); + } + + private static void printEnchantment(@NotNull Player p, @NotNull Shop shop, ChatSheetPrinter chatSheetPrinter) { + if (shop.getItem().hasItemMeta() && shop.getItem().getItemMeta().hasItemFlag(ItemFlag.HIDE_ENCHANTS) && plugin.getConfig().getBoolean("respect-item-flag")) { + return; + } + Map enchs = new HashMap<>(); + if (shop.getItem().hasItemMeta() && shop.getItem().getItemMeta().hasEnchants()) { + enchs = shop.getItem().getItemMeta().getEnchants(); + } + if (!enchs.isEmpty()) { + chatSheetPrinter.printCenterLine(MsgUtil.getMessage("menu.enchants", p)); + for (Entry entries : enchs.entrySet()) { + chatSheetPrinter.printLine(ChatColor.YELLOW + MsgUtil.getEnchi18n(entries.getKey())); + } + } + if (shop.getItem().getItemMeta() instanceof EnchantmentStorageMeta) { + EnchantmentStorageMeta stor = (EnchantmentStorageMeta) shop.getItem().getItemMeta(); + stor.getStoredEnchants(); + enchs = stor.getStoredEnchants(); + if (!enchs.isEmpty()) { + chatSheetPrinter.printCenterLine(MsgUtil.getMessage("menu.stored-enchants", p)); + for (Entry entries : enchs.entrySet()) { + chatSheetPrinter.printLine(ChatColor.YELLOW + MsgUtil.getEnchi18n(entries.getKey())); + } + } + } + } + + /** + * Send a shop infomation to a player. + * + * @param p Target player + * @param shop The shop + */ + public static void sendShopInfo(@NotNull Player p, @NotNull Shop shop) { + // Potentially faster with an array? + ItemStack items = shop.getItem(); + ChatSheetPrinter chatSheetPrinter = new ChatSheetPrinter(p); + chatSheetPrinter.printHeader(); + chatSheetPrinter.printLine(MsgUtil.getMessage("menu.shop-information", p)); + chatSheetPrinter.printLine(MsgUtil.getMessage("menu.owner", p, shop.ownerName())); + // Enabled + sendItemholochat( + shop, + items, + p, + ChatColor.DARK_PURPLE + + MsgUtil.getMessage("tableformat.left_begin", p) + + " " + + MsgUtil.getMessage("menu.item", p, Util.getItemStackName(items))); + if (Util.isTool(items.getType())) { + chatSheetPrinter.printLine( + MsgUtil.getMessage("menu.damage-percent-remaining", p, Util.getToolPercentage(items))); + } + if (shop.isSelling()) { + if (shop.getRemainingStock() == -1) { + chatSheetPrinter.printLine( + MsgUtil.getMessage("menu.stock", p, "" + MsgUtil.getMessage("signs.unlimited", p))); + } else { + chatSheetPrinter.printLine( + MsgUtil.getMessage("menu.stock", p, "" + shop.getRemainingStock())); + } + } else { + if (shop.getRemainingSpace() == -1) { + chatSheetPrinter.printLine( + MsgUtil.getMessage("menu.space", p, "" + MsgUtil.getMessage("signs.unlimited", p))); + } else { + chatSheetPrinter.printLine( + MsgUtil.getMessage("menu.space", p, "" + shop.getRemainingSpace())); + } + } + chatSheetPrinter.printLine( + MsgUtil.getMessage( + "menu.price-per", + p, + Util.getItemStackName(shop.getItem()), + Util.format(shop.getPrice()))); + if (shop.isBuying()) { + chatSheetPrinter.printLine(MsgUtil.getMessage("menu.this-shop-is-buying", p)); + } else { + chatSheetPrinter.printLine(MsgUtil.getMessage("menu.this-shop-is-selling", p)); + } + printEnchantment(p, shop, chatSheetPrinter); + if (items.getItemMeta() instanceof PotionMeta) { + PotionMeta potionMeta = (PotionMeta) items.getItemMeta(); + PotionEffectType potionEffectType = potionMeta.getBasePotionData().getType().getEffectType(); + if (potionEffectType != null) { + chatSheetPrinter.printLine(MsgUtil.getMessage("menu.effects", p)); + chatSheetPrinter.printLine(ChatColor.YELLOW + MsgUtil.getPotioni18n(potionEffectType)); + } + potionMeta + .getCustomEffects() + .forEach( + (potionEffect -> + chatSheetPrinter.printLine( + ChatColor.YELLOW + MsgUtil.getPotioni18n(potionEffect.getType())))); + } + chatSheetPrinter.printFooter(); + } + + /** + * Send the ItemPreview chat msg by NMS. + * + * @param shop Target shop + * @param itemStack Target ItemStack + * @param player Target player + * @param normalText The text you will see + */ + public static void sendItemholochat( + @NotNull Shop shop, + @NotNull ItemStack itemStack, + @NotNull Player player, + @NotNull String normalText) { + try { + String json = ItemNMS.saveJsonfromNMS(itemStack); + if (json == null) { + return; + } + TextComponent normalmessage = + new TextComponent(normalText + " " + MsgUtil.getMessage("menu.preview", player)); + ComponentBuilder cBuilder = new ComponentBuilder(json); + if (QuickShop.getPermissionManager().hasPermission(player, "quickshop.preview")) { + normalmessage.setClickEvent( + new ClickEvent( + ClickEvent.Action.RUN_COMMAND, + MsgUtil.getMessage( + "menu.commands.preview", + player, + Objects.requireNonNull(shop.getLocation().getWorld()).getName(), + String.valueOf(shop.getLocation().getBlockX()), + String.valueOf(shop.getLocation().getBlockY()), + String.valueOf(shop.getLocation().getBlockZ())))); + } + normalmessage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, cBuilder.create())); + player.spigot().sendMessage(normalmessage); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + /** + * Get potion effect's i18n name. + * + * @param potion potionType + * @return Potion's i18n name. + */ + public static String getPotioni18n(@NotNull PotionEffectType potion) { + String potionString = potion.getName().trim(); + if (potionString.isEmpty()) { + return "Potion name is empty."; + } + String potionI18n = potioni18n.getString("potioni18n." + potionString); + if (potionI18n != null && !potionI18n.isEmpty()) { + return potionI18n; + } + return Util.prettifyText(potionString); + } + + public static IFile getI18nFile() { + return messagei18n; + } + + @SneakyThrows + @SuppressWarnings("UnusedAssignment") + private static void updateMessages(int selectedVersion) { + String languageName = plugin.getConfig().getString("language", "en"); + if (!messagei18n.getString("language-name").isPresent()) { + setAndUpdate("language-name", languageName); + } + if (!messagei18n.getString("language-name").get().equals(languageName)) { + Util.debugLog("Language name " + messagei18n.getString("language-name").get() + " not matched with " + languageName); + File pendingDelete = new File(plugin.getDataFolder(), "messages.json"); + try { + Files.copy(pendingDelete.toPath(), new File(plugin.getDataFolder(), "messages-bak-" + UUID.randomUUID().toString() + ".json").toPath()); + } catch (IOException ignored) { + } + pendingDelete.delete(); + try { + loadCfgMessages(); + } catch (Exception ignore) { + } + return; + } + + builtInLang = new JSONFile(plugin, "lang/" + languageName + "/messages.json"); + + if (selectedVersion == 1) { + setAndUpdate("shop-not-exist", "&cThere had no shop."); + setAndUpdate("controlpanel.infomation", "&aShop Control Panel:"); + setAndUpdate("controlpanel.setowner", "&aOwner: &b{0} &e[&d&lChange&e]"); + setAndUpdate( + "controlpanel.setowner-hover", + "&eLooking you want changing shop and click to switch owner."); + setAndUpdate("controlpanel.unlimited", "&aUnlimited: {0} &e[&d&lSwitch&e]"); + messagei18n.set( + "controlpanel.unlimited-hover", + "&eLooking you want changing shop and click to switch enabled or disabled."); + setAndUpdate("controlpanel.mode-selling", "&aShop mode: &bSelling &e[&d&lSwitch&e]"); + messagei18n.set( + "controlpanel.mode-selling-hover", + "&eLooking you want changing shop and click to switch enabled or disabled."); + setAndUpdate("controlpanel.mode-buying", "&aShop mode: &bBuying &e[&d&lSwitch&e]"); + messagei18n.set( + "controlpanel.mode-buying-hover", + "&eLooking you want changing shop and click to switch enabled or disabled."); + setAndUpdate("controlpanel.price", "&aPrice: &b{0} &e[&d&lSet&e]"); + setAndUpdate( + "controlpanel.price-hover", + "&eLooking you want changing shop and click to set new price."); + setAndUpdate("controlpanel.refill", "&aRefill: Refill the shop items &e[&d&lOK&e]"); + setAndUpdate( + "controlpanel.refill-hover", "&eLooking you want changing shop and click to refill."); + setAndUpdate("controlpanel.empty", "&aEmpty: Remove shop all items &e[&d&lOK&e]"); + setAndUpdate( + "controlpanel.empty-hover", "&eLooking you want changing shop and click to clear."); + setAndUpdate("controlpanel.remove", "&c&l[Remove Shop]"); + setAndUpdate("controlpanel.remove-hover", "&eClick to remove this shop."); + setAndUpdate("language-version", 2); + selectedVersion = 2; + } + if (selectedVersion == 2) { + setAndUpdate("command.no-target-given", "&cUsage: /qs export mysql|sqlite"); + setAndUpdate("command.description.debug", "&ePrint debug infomation"); + messagei18n.set( + "no-permission-remove-shop", + "&cYou do not have permission to use that command. Try break the shop instead?"); + setAndUpdate("language-version", 3); + selectedVersion = 3; + } + if (selectedVersion == 3) { + setAndUpdate("signs.unlimited", "Unlimited"); + setAndUpdate("controlpanel.sign.owner.line1", ""); + setAndUpdate("controlpanel.sign.owner.line2", "Enter"); + setAndUpdate("controlpanel.sign.owner.line3", "new owner name"); + setAndUpdate("controlpanel.sign.owner.line4", "at first line"); + setAndUpdate("controlpanel.sign.price.line1", ""); + setAndUpdate("controlpanel.sign.price.line2", "Enter"); + setAndUpdate("controlpanel.sign.price.line3", "new shop price"); + setAndUpdate("controlpanel.sign.price.line4", "at first line"); + setAndUpdate("controlpanel.sign.refill.line1", ""); + setAndUpdate("controlpanel.sign.refill.line2", "Enter amount"); + setAndUpdate("controlpanel.sign.refill.line3", "you want fill"); + setAndUpdate("controlpanel.sign.refill.line4", "at first line"); + setAndUpdate("language-version", 4); + selectedVersion = 4; + } + if (selectedVersion == 4) { + setAndUpdate("signs.unlimited", "Unlimited"); + setAndUpdate("controlpanel.sign", null); + setAndUpdate("language-version", 5); + selectedVersion = 5; + } + if (selectedVersion == 5) { + setAndUpdate("command.description.fetchmessage", "&eFetch unread shop message"); + setAndUpdate("nothing-to-flush", "&aYou had no new shop message."); + setAndUpdate("language-version", 6); + selectedVersion = 6; + } + if (selectedVersion == 6) { + setAndUpdate("command.description.info", "&eShow QuickShop Statistics"); + setAndUpdate("command.description.debug", "&eSwitch to developer mode"); + setAndUpdate("break-shop-use-supertool", "&eYou break the shop by use SuperTool."); + messagei18n.set( + "no-creative-break", + "&cYou cannot break other players shops in creative mode. Use survival instead or use SuperTool ({0})."); + setAndUpdate( + "command.now-debuging", + "&aSuccessfully switch to developer mode, Reloading QuickShop..."); + setAndUpdate( + "command.now-nolonger-debuging", + "&aSuccessfully switch to production mode, Reloading QuickShop..."); + setAndUpdate("language-version", 7); + selectedVersion = 7; + } + if (selectedVersion == 7) { + setAndUpdate( + "failed-to-put-sign", "&cNo enough space around the shop to place infomation sign."); + setAndUpdate("language-version", 8); + selectedVersion = 8; + } + if (selectedVersion == 8) { + messagei18n.set( + "failed-to-paste", + "&cFailed upload data to Pastebin, Check the internet and try again. (See console for details)"); + messagei18n.set( + "warn-to-paste", + "&eCollecting data and upload to Pastebin, this may need a while. &c&lWarning&c, The data is keep public one week, it may leak your server configuration, make sure you only send it to your <rusted staff/developer."); + setAndUpdate("command.description.paste", "&eAuto upload server data to Pastebin"); + setAndUpdate("language-version", 9); + selectedVersion = 9; + } + if (selectedVersion == 9) { + setAndUpdate("controlpanel.commands.setowner", "/qs owner [Player]"); + setAndUpdate("controlpanel.commands.unlimited", "/qs slientunlimited {0} {1} {2} {3}"); + setAndUpdate("controlpanel.commands.buy", "/qs silentbuy {0} {1} {2} {3}"); + setAndUpdate("controlpanel.commands.sell", "/qs silentsell {0} {1} {2} {3}"); + setAndUpdate("controlpanel.commands.price", "/qs price [New Price]"); + setAndUpdate("controlpanel.commands.refill", "/qs refill [Amount]"); + setAndUpdate("controlpanel.commands.empty", "/qs silentempty {0} {1} {2} {3}"); + setAndUpdate("controlpanel.commands.remove", "/qs silentremove {0} {1} {2} {3}"); + setAndUpdate( + "tableformat.full_line", "+---------------------------------------------------+"); + setAndUpdate("tableformat.left_half_line", "+--------------------"); + setAndUpdate("tableformat.right_half_line", "--------------------+"); + setAndUpdate("tableformat.left_begin", "| "); + setAndUpdate("booleanformat.success", "&a✔"); + setAndUpdate("booleanformat.failed", "&c✘"); + setAndUpdate("language-version", 10); + selectedVersion = 10; + } + if (selectedVersion == 10) { + setAndUpdate( + "price-too-high", "&cShop price too high! You can't create price higher than {0} shop."); + setAndUpdate("language-version", 11); + selectedVersion = 11; + } + if (selectedVersion == 11) { + setAndUpdate( + "unknown-player", "&cTarget player not exist, please check username your typed."); + setAndUpdate("shop-staff-cleared", "&aSuccessfully remove all staff for your shop."); + setAndUpdate("shop-staff-added", "&aSuccessfully add {0} to your shop staffs."); + setAndUpdate("shop-staff-deleted", "&aSuccessfully remove {0} to your shop staffs."); + setAndUpdate("command.wrong-args", "&cParameters not matched, use /qs help to check help"); + setAndUpdate("command.description.staff", "&eManage your shop staffs."); + setAndUpdate( + "unknown-player", "&cTarget player not exist, please check username your typed."); + setAndUpdate("language-version", 12); + selectedVersion = 12; + } + if (selectedVersion == 12) { + setAndUpdate("menu.commands.preview", "/qs silentpreview {0} {1} {2} {3}"); + setAndUpdate("shop-staff-cleared", "&aSuccessfully remove all staff for your shop."); + setAndUpdate("shop-staff-added", "&aSuccessfully add {0} to your shop staffs."); + setAndUpdate("shop-staff-deleted", "&aSuccessfully remove {0} to your shop staffs."); + setAndUpdate("command.wrong-args", "&cParameters not matched, use /qs help to check help"); + setAndUpdate("command.description.staff", "&eManage your shop staffs."); + setAndUpdate( + "unknown-player", "&cTarget player not exist, please check username your typed."); + setAndUpdate("language-version", 13); + selectedVersion = 13; + } + if (selectedVersion == 13) { + setAndUpdate("no-permission-build", "&cYou can't build shop here."); + setAndUpdate("success-change-owner-to-server", "&aSuccessfully set shop owner to Server."); + setAndUpdate("updatenotify.buttontitle", "[Update Now]"); + List notifylist = new ArrayList<>(); + notifylist.add("{0} is released, You still using {1}!"); + notifylist.add("Boom! New update {0} incoming, Update!"); + notifylist.add("Surprise! {0} come out, you are on {1}"); + notifylist.add("Looks you need update, {0} is updated!"); + notifylist.add("Ooops! {0} new released, you are {1}!"); + notifylist.add("I promise, QS updated {0}, why not update?"); + notifylist.add("Fixing and re... Sorry {0} is updated!"); + notifylist.add("Err! Nope, not error, just {0} updated!"); + notifylist.add("OMG! {0} come out! Why you still use {1}?"); + notifylist.add("Today News: QuickShop updated {0}!"); + notifylist.add("Plugin K.I.A, You should update {0}!"); + notifylist.add("Fuze is fuzeing update {0}, save update!"); + notifylist.add("You are update commander, told u {0} come out!"); + notifylist.add("Look me style---{0} updated, you still {1}"); + notifylist.add("Ahhhhhhh! New update {0}! Update!"); + notifylist.add("What U thinking? {0} released! Update!"); + setAndUpdate("updatenotify.list", notifylist); + setAndUpdate("language-version", 14); + selectedVersion = 14; + } + if (selectedVersion == 14) { + setAndUpdate("flush-finished", "&aSuccessfully flushed the messages."); + setAndUpdate("language-version", 15); + selectedVersion = 15; + } + if (selectedVersion == 15) { + setAndUpdate( + "purchase-failed", + "&cPurchase failed: Internal Error, please contact the server administrator.."); + setAndUpdate("language-version", 16); + selectedVersion = 16; + } + if (selectedVersion == 16) { + setAndUpdate("command.description.owner", "&eChanges who owns a shop"); + setAndUpdate("command.description.remove", "&eRemove your looking the shop"); + setAndUpdate( + "command.description.amount", + "&eExecute for your actions with amount(For chat plugin issue)"); + setAndUpdate("command.description.about", "&eShow QuickShop abouts"); + setAndUpdate("command.description.help", "&eShow QuickShop helps"); + setAndUpdate("no-pending-action", "&cYou do not have any pending action"); + setAndUpdate("language-version", 17); + selectedVersion = 17; + } + if (selectedVersion == 17) { + setAndUpdate("updatenotify.onekeybuttontitle", "[OneKey Update]"); + setAndUpdate("language-version", 18); + selectedVersion = 18; + } + if (selectedVersion == 18) { + setAndUpdate( + "command.description.supercreate", "&eCreate a shop bypass all protection checks"); + setAndUpdate("language-version", 19); + selectedVersion = 19; + } + if (selectedVersion == 19) { + setAndUpdate("permission-denied-3rd-party", "&cPermission denied: 3rd party plugin [{0}]."); + setAndUpdate( + "updatenotify.remote-disable-warning", + "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running."); + setAndUpdate("language-version", 20); + selectedVersion = 20; + } + if (selectedVersion == 20) { + setAndUpdate( + "how-many-buy", + "&aEnter how many you wish to &bBUY&a in chat. Enter &ball&a to buy them all."); + setAndUpdate( + "how-many-sell", + "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all."); + setAndUpdate("updatenotify.label.unstable", "[Unstable]"); + setAndUpdate("updatenotify.label.stable", "[Stable]"); + setAndUpdate("updatenotify.label.lts", "[LTS]"); + setAndUpdate("updatenotify.label.qualityverifyed", "[Quality]"); + setAndUpdate("updatenotify.label.github", "[Github]"); + setAndUpdate("updatenotify.label.spigotmc", "[SpigotMC]"); + setAndUpdate("updatenotify.label.bukkitdev", "[BukkitDev]"); + setAndUpdate("language-version", 21); + selectedVersion = 21; + } + if (selectedVersion == 21) { + setAndUpdate( + "shop-removed-cause-ongoing-fee", + "&cYou shop at {0} was removed cause you had no enough money to keep it!"); + setAndUpdate("language-version", 22); + selectedVersion = 22; + } + if (selectedVersion == 22) { + setAndUpdate("not-a-number", "&cThere can only be number, but you input {0}"); + setAndUpdate("not-a-integer", "&cThere can only be integer, but you input {0}"); + setAndUpdate("language-version", 23); + selectedVersion = 23; + } + if (selectedVersion == 23) { + setAndUpdate("command.toggle-unlimited.unlimited", "&aShop is now unlimited}"); + setAndUpdate("command.toggle-unlimited.limited", "&aShop is now limited"); + setAndUpdate("language-version", 24); + selectedVersion = 24; + } + if (selectedVersion == 24) { + setAndUpdate( + "digits-reach-the-limit", + "&cYou have reach the limit of the digits after the dot in price."); + setAndUpdate("language-version", 25); + selectedVersion = 25; + } + if (selectedVersion == 25) { + setAndUpdate("complete", "&aComplete!"); + setAndUpdate("language-version", 26); + selectedVersion = 26; + } + if (selectedVersion == 26) { + setAndUpdate("updatenotify.label.master", "[Master]"); + setAndUpdate("language-version", 27); + selectedVersion = 27; + } + if (selectedVersion == 27) { + setAndUpdate("quickshop-gui-preview", "QuickShop GUI Preview Item"); + setAndUpdate("shops-recovering", "Recovering shops from backup..."); + setAndUpdate("shops-backingup", "Backing up the shops from database..."); + setAndUpdate("saved-to-path", "The backup file was saved to {0} ."); + setAndUpdate("backup-failed", "Cannot backup the database, check the console for details."); + setAndUpdate("translate-not-completed-yet-click", "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!"); + setAndUpdate("translate-not-completed-yet-url", "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}"); + setAndUpdate("language-info-panel.name", "Language: "); + setAndUpdate("language-info-panel.code", "Code: "); + setAndUpdate("language-info-panel.progress", "Progress: "); + setAndUpdate("language-info-panel.help", "Help Us: "); + setAndUpdate("language-info-panel.translate-on-crowdin", "[Translate on Crowdin]"); + setAndUpdate("not-managed-shop", "You isn't the owner or moderator of the shop"); + setAndUpdate("language-version", 28); + selectedVersion = 28; + } + if (selectedVersion == 28) { + setAndUpdate("quickshop-gui-preview", "QuickShop GUI Preview Item"); + setAndUpdate("shops-recovering", "Recovering shops from backup..."); + setAndUpdate("shops-backingup", "Backing up the shops from database..."); + setAndUpdate("saved-to-path", "The backup file was saved to {0} ."); + setAndUpdate("backup-failed", "Cannot backup the database, check the console for details."); + setAndUpdate("translate-not-completed-yet-click", "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!"); + setAndUpdate("translate-not-completed-yet-url", "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}"); + setAndUpdate("language-info-panel.name", "Language: "); + setAndUpdate("language-info-panel.code", "Code: "); + setAndUpdate("language-info-panel.progress", "Progress: "); + setAndUpdate("language-info-panel.help", "Help Us: "); + setAndUpdate("language-info-panel.translate-on-crowdin", "[Translate on Crowdin]"); + setAndUpdate("not-managed-shop", "You isn't the owner or moderator of the shop"); + setAndUpdate("language-version", 29); + selectedVersion = 29; + } + if (selectedVersion == 29) { + setAndUpdate("3rd-plugin-build-check-failed", "Some 3rd party plugin denied the permission checks, did you have permission built in there?"); + setAndUpdate("language-version", 30); + selectedVersion = 30; + } + if (selectedVersion == 30) { + setAndUpdate("no-creative-break", "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead."); + setAndUpdate("trading-in-creative-mode-is-disabled", "&cYou cannot trade with shop in the creative mode."); + setAndUpdate("supertool-is-disabled", "&cSupertool is disabled, cannot break any shop."); + setAndUpdate("language-version", 31); + selectedVersion = 31; + } + + messagei18n.save(); + messagei18n.loadFromString(Util.parseColours(messagei18n.saveToString())); + } + + private static void setAndUpdate(@NotNull String path, @Nullable Object object) { + if (object == null) { + messagei18n.set(path, null); // Removal + return; + } + Object alt = null; + if (builtInLang != null) { + alt = builtInLang.get(path, object); + } + if (alt == null) { + messagei18n.set(path, object); + } else { + messagei18n.set(path, alt); + } +// Object objFromBuiltIn = builtInDefaultLanguage.get(path); / Apply english default +// if (objFromBuiltIn == null) { +// objFromBuiltIn = +// object; // Apply hard-code default, maybe a language file i forgotten update?? +// } + } + public static void sendMessage(@NotNull CommandSender sender, @Nullable String... messages){ + if(messages == null){ + return; + } + for (String msg : messages){ + if(msg == null || msg.isEmpty()){ + continue; + } + MsgUtil.sendMessage(sender,msg); + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/PermissionChecker.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/PermissionChecker.java new file mode 100644 index 0000000..2f0091e --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/PermissionChecker.java @@ -0,0 +1,124 @@ +/* + * This file is a part of project QuickShop, the name is PermissionChecker.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import java.util.concurrent.atomic.AtomicBoolean; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.jetbrains.annotations.NotNull; +import org.abc.A.G.ProtectionCheckStatus; +import org.abc.A.G.ShopProtectionCheckEvent; +import org.abc.A.QuickShop; +import org.primesoft.blockshub.BlocksHubBukkit; + +public class PermissionChecker { + private final QuickShop plugin; + + private final boolean usePermissionChecker; + + public PermissionChecker(@NotNull QuickShop plugin) { + this.plugin = plugin; + usePermissionChecker = this.plugin.getConfig().getBoolean("shop.protection-checking"); + } + + /** + * Check player can build in target location + * + * @param player Target player + * @param location Target location + * @return Success + */ + public boolean canBuild(@NotNull Player player, @NotNull Location location) { + return canBuild(player, location.getBlock()); + } + + /** + * Check player can build in target block + * + * @param player Target player + * @param block Target block + * @return Success + */ + public boolean canBuild(@NotNull Player player, @NotNull Block block) { + if (!usePermissionChecker) { + return true; + } + final AtomicBoolean isCanBuild = new AtomicBoolean(false); + + if (plugin.getBlockHubPlugin() != null) { + BlocksHubBukkit blocksHubBukkit = (BlocksHubBukkit) plugin.getBlockHubPlugin(); + boolean bhCanBuild = blocksHubBukkit.getApi().hasAccess(player.getUniqueId(), blocksHubBukkit.getApi().getWorld(block.getWorld().getName()), block.getX(), block.getY(), block.getZ()); + if (plugin.getConfig().getBoolean("plugin.BlockHub.only")) { + Util.debugLog("BlockHub only mode response: " + bhCanBuild); + return bhCanBuild; + } else { + if (!bhCanBuild) { + Util.debugLog("BlockHub reporting player no permission to access this region."); + return false; + } + } + } + + BlockBreakEvent beMainHand; + // beMainHand = new BlockPlaceEvent(block, block.getState(), block.getRelative(0, -1, 0), + // player.getInventory() + // getItemInMainHand(), player, true, EquipmentSlot.HAND); + + beMainHand = new BlockBreakEvent(block, player); + // Call for event for protection check start + Bukkit.getPluginManager() + .callEvent( + new ShopProtectionCheckEvent( + block.getLocation(), player, ProtectionCheckStatus.BEGIN, beMainHand)); + beMainHand.setDropItems(false); + beMainHand.setExpToDrop(0); + + //register a listener to cancel test event + Bukkit.getPluginManager().registerEvents(new Listener() { + @EventHandler(priority = EventPriority.HIGHEST) + public void onTestEvent(BlockBreakEvent event) { + if (event == beMainHand) { + // Call for event for protection check end + Bukkit.getPluginManager().callEvent( + new ShopProtectionCheckEvent( + block.getLocation(), player, ProtectionCheckStatus.END, beMainHand)); + if (!event.isCancelled()) { + //Ensure this test will no be logged by some plugin + beMainHand.setCancelled(true); + isCanBuild.set(true); + } + HandlerList.unregisterAll(this); + } + } + }, plugin); + + Bukkit.getPluginManager().callEvent(beMainHand); + + return isCanBuild.get(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/ReflectFactory.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/ReflectFactory.java new file mode 100644 index 0000000..02da988 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/ReflectFactory.java @@ -0,0 +1,46 @@ +/* + * This file is a part of project QuickShop, the name is ReflectFactory.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import org.bukkit.Bukkit; + +import java.lang.reflect.Field; + +public class ReflectFactory { + private static String cachedVersion = null; + public static String getServerVersion() { + if(cachedVersion != null){ + return cachedVersion; + } + try { + Field consoleField = Bukkit.getServer().getClass().getDeclaredField("console"); + consoleField.setAccessible(true); // protected + Object console = consoleField.get(Bukkit.getServer()); // dedicated server + cachedVersion = String.valueOf( + console.getClass().getSuperclass().getMethod("getVersion").invoke(console)); + return cachedVersion; + } catch (Exception e) { + e.printStackTrace(); + cachedVersion = "Unknown"; + return cachedVersion; + } + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/RomanNumber.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/RomanNumber.java new file mode 100644 index 0000000..0b22869 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/RomanNumber.java @@ -0,0 +1,54 @@ +/* + * This file is a part of project QuickShop, the name is RomanNumber.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import java.util.TreeMap; + +/** + * @author "Ben-Hur Langoni Junior" on StackOverFlow page "https://stackoverflow.com/a/19759564" + */ +public class RomanNumber { + private static final TreeMap map = new TreeMap<>(); + + static { + map.put(1000, "M"); + map.put(900, "CM"); + map.put(500, "D"); + map.put(400, "CD"); + map.put(100, "C"); + map.put(90, "XC"); + map.put(50, "L"); + map.put(40, "XL"); + map.put(10, "X"); + map.put(9, "IX"); + map.put(5, "V"); + map.put(4, "IV"); + map.put(1, "I"); + } + + public static String toRoman(int number) { + int l = map.floorKey(number); + if (number == l) { + return map.get(number); + } + return map.get(l) + toRoman(number - l); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/SentryErrorReporter.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/SentryErrorReporter.java new file mode 100644 index 0000000..6628648 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/SentryErrorReporter.java @@ -0,0 +1,387 @@ +/* + * This file is a part of project QuickShop, the name is SentryErrorReporter.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import io.sentry.SentryClient; +import io.sentry.SentryClientFactory; +import io.sentry.context.Context; +import io.sentry.event.BreadcrumbBuilder; +import io.sentry.event.UserBuilder; +import java.io.IOException; +import java.net.ProtocolException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import java.util.logging.Filter; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; +import lombok.Getter; +import org.abc.A.util.paste.Paste; +import org.bukkit.Bukkit; +import org.bukkit.plugin.InvalidPluginException; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.QuickShop; +import org.abc.A.O.UpdateWatcher; + +/** + * Auto report errors to qs's sentry. + */ +public class SentryErrorReporter { + private final String dsn = + "https://1d14223850ee44b284b11734461ebbc5@sentry.io/1473041?" + + "stacktrace.app.packages=org.maxgamer.quickshop"; + + private final ArrayList reported = new ArrayList<>(); + + private final Context context; + + private final List> ignoredException = new ArrayList<>(); + + private final QuickShop plugin; + + /* Pre-init it if it called before the we create it... */ + private final SentryClient sentryClient; + + private final IncompatibleChecker checker = new IncompatibleChecker(); + + private boolean disable; + + @Getter + private boolean enabled; + + private boolean tempDisable; + + private String lastPaste = "Failed to paste."; + + public SentryErrorReporter(@NotNull QuickShop plugin) { + this.plugin = plugin; + // sentryClient = Sentry.init(dsn); + Util.debugLog("Loading SentryErrorReporter"); + sentryClient = SentryClientFactory.sentryClient(dsn); + context = sentryClient.getContext(); + Util.debugLog("Setting basic report data..."); + // context.addTag("plugin_version", QuickShop.getVersion()); + context.addTag("system_os", System.getProperty("os.name")); + context.addTag("system_arch", System.getProperty("os.arch")); + context.addTag("system_version", System.getProperty("os.version")); + context.addTag("system_cores", String.valueOf(Runtime.getRuntime().availableProcessors())); + context.addTag("server_build", Bukkit.getServer().getVersion()); + context.addTag("server_java", String.valueOf(System.getProperty("java.version"))); + context.addTag( + "server_players", Bukkit.getOnlinePlayers().size() + "/" + Bukkit.getMaxPlayers()); + context.addTag("server_onlinemode", String.valueOf(Bukkit.getOnlineMode())); + context.addTag("server_bukkitversion", Bukkit.getVersion()); + context.addTag("server_plugins", getPluginInfo()); + context.setUser( + new UserBuilder() + .setId(plugin.getServerUniqueID().toString()) + .setUsername(plugin.getServerUniqueID().toString()) + .build()); + sentryClient.setServerName( + Bukkit.getServer().getName() + " @ " + Bukkit.getServer().getVersion()); + sentryClient.setRelease(QuickShop.getVersion()); + sentryClient.setEnvironment(Util.isDevEdition() ? "development" : "production"); + plugin + .getLogger() + .setFilter( + new QuickShopExceptionFilter()); // Redirect log request passthrough our error catcher. + Bukkit.getLogger().setFilter(new GlobalExceptionFilter()); + Bukkit.getServer().getLogger().setFilter(new GlobalExceptionFilter()); + Logger.getGlobal().setFilter(new GlobalExceptionFilter()); + /* Ignore we won't report errors */ + ignoredException.add(IOException.class); + ignoredException.add(OutOfMemoryError.class); + ignoredException.add(ProtocolException.class); + ignoredException.add(InvalidPluginException.class); + ignoredException.add(UnsupportedClassVersionError.class); + ignoredException.add(LinkageError.class); + + Util.debugLog("Sentry error reporter success loaded."); + enabled = true; + if (!plugin.getConfig().getBoolean("auto-report-errors")) { + Util.debugLog("Sentry error report was disabled, unloading..."); + unit(); + return; + } + new BukkitRunnable() { + @Override + public void run() { + Paste paste = new Paste(plugin); + lastPaste = paste.paste(paste.genNewPaste(), 1); + if (lastPaste != null) { + plugin.log("Plugin booted up, the server paste was created for debugging, reporting errors and data-recovery: " + lastPaste); + } + } + }.runTaskAsynchronously(plugin); + } + + private String getPluginInfo() { + StringBuilder buffer = new StringBuilder(); + for (Plugin bplugin : Bukkit.getPluginManager().getPlugins()) { + buffer + .append("\t") + .append(bplugin.getName()) + .append("@") + .append(bplugin.isEnabled() ? "Enabled" : "Disabled") + .append("\n"); + } + return buffer.toString(); + } + + /** + * Unload Sentry error reporter + */ + private void unit() { + enabled = false; + } + + /** + * Dupe report check + * + * @param throwable Throws + * @return dupecated + */ + public boolean canReport(@NotNull Throwable throwable) { + if (!enabled) { + return false; + } + if (UpdateWatcher.hasNewUpdate) { // We only receive latest reports. + return false; + } + if (checker + .isIncompatible( + Util + .getNMSVersion())) { // Ignore errors if user install quickshop on unsupported + // version. + return false; + } + if (!checkWasCauseByQS(throwable)) { + return false; + } + StackTraceElement stackTraceElement; + if (throwable.getStackTrace().length < 3) { + stackTraceElement = throwable.getStackTrace()[1]; + } else { + stackTraceElement = throwable.getStackTrace()[2]; + } + String text = + stackTraceElement.getClassName() + + "#" + + stackTraceElement.getMethodName() + + "#" + + stackTraceElement.getLineNumber(); + if (!reported.contains(text)) { + reported.add(text); + return true; + } else { + return false; + } + } + + /** + * Check a throw is cause by QS + * + * @param throwable Throws + * @return Cause or not + */ + public boolean checkWasCauseByQS(@Nullable Throwable throwable) { + if (throwable == null) { + return false; + } + if (throwable.getMessage() == null) { + return false; + } + if (throwable.getMessage().contains("Could not pass event")) { + return throwable.getMessage().contains("QuickShop"); + } + while (throwable.getCause() != null) { + throwable = throwable.getCause(); + } + long element = + Arrays.stream(throwable.getStackTrace()) + .limit(5) + .filter( + stackTraceElement -> + stackTraceElement.getClassName().contains("org.abc.A")) + .count(); + if (element > 0) { + return true; + } else if (throwable.getCause() != null) { + return checkWasCauseByQS(throwable.getCause()); + } + return false; + } + + /** + * Set ignore throw. It will unlocked after accept a throw + */ + public void ignoreThrow() { + tempDisable = true; + } + + /** + * Set ignore throws. It will unlocked after called method resetIgnores. + */ + public void ignoreThrows() { + disable = true; + } + + /** + * Reset ignore throw(s). + */ + public void resetIgnores() { + tempDisable = false; + disable = false; + } + + /** + * Send a error to Sentry + * + * @param throwable Throws + * @param context BreadCrumb + * @return Event Uniqud ID + */ + public @Nullable UUID sendError(@NotNull Throwable throwable, @NotNull String... context) { + try { + if (QuickShop.instance.getBootError() != null) { + return null; // Don't report any errors if boot failed. + } + if (tempDisable) { + this.tempDisable = false; + return null; + } + if (disable) { + return null; + } + if (!enabled) { + return null; + } + + if (!checkWasCauseByQS(throwable)) { + return null; + } + + if (!canReport(throwable)) { + return null; + } + if (ignoredException.contains(throwable.getClass())) { + return null; + } + for (String record : context) { + this.context.recordBreadcrumb(new BreadcrumbBuilder().setMessage(record).build()); + } + String pasteURL = "Failed to paste."; + try { + Paste paste = new Paste(plugin); + pasteURL = paste.paste(paste.genNewPaste()); + if (pasteURL != null && !pasteURL.isEmpty()) { + lastPaste = pasteURL; + } + } catch (Throwable ex) { + // Ignore + pasteURL = this.lastPaste; + } + this.context.addTag("paste", pasteURL); + this.sentryClient.sendException(throwable); + this.context.clearBreadcrumbs(); + plugin + .getLogger() + .warning( + "A exception was thrown, QuickShop already caught this exception and reported it, switch to debug mode to see the full errors."); + plugin.getLogger().warning("====QuickShop Error Report BEGIN==="); + plugin.getLogger().warning("Description: " + throwable.getMessage()); + plugin.getLogger().warning("Event ID: " + this.context.getLastEventId()); + plugin.getLogger().warning("Server ID: " + plugin.getServerUniqueID()); + plugin.getLogger().warning("====QuickShop Error Report E N D==="); + Util.debugLog(throwable.getMessage()); + Arrays.stream(throwable.getStackTrace()).forEach(a -> Util.debugLog(a.getClassName() + "." + a.getMethodName() + ":" + a.getLineNumber())); + if (Util.isDevMode()) { + throwable.printStackTrace(); + } + return this.context.getLastEventId(); + } catch (Throwable th) { + th.printStackTrace(); + return null; + } + } + + class GlobalExceptionFilter implements Filter { + + /** + * Check if a given log record should be published. + * + * @param record a LogRecord + * @return true if the log record should be published. + */ + @Override + public boolean isLoggable(@NotNull LogRecord record) { + if (!enabled) { + return true; + } + Level level = record.getLevel(); + if (level != Level.WARNING && level != Level.SEVERE) { + return true; + } + if (Util.isDevMode()) { + sendError(record.getThrown(), record.getMessage()); + return true; + } else { + return sendError(record.getThrown(), record.getMessage()) == null; + } + } + + } + + class QuickShopExceptionFilter implements Filter { + + /** + * Check if a given log record should be published. + * + * @param record a LogRecord + * @return true if the log record should be published. + */ + @Override + public boolean isLoggable(@NotNull LogRecord record) { + if (!enabled) { + return true; + } + Level level = record.getLevel(); + if (level != Level.WARNING && level != Level.SEVERE) { + return true; + } + if (record.getThrown() == null) { + return true; + } + if (Util.isDevMode()) { + sendError(record.getThrown(), record.getMessage()); + return true; + } else { + return sendError(record.getThrown(), record.getMessage()) == null; + } + } + + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Timer.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Timer.java new file mode 100644 index 0000000..8f300a8 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Timer.java @@ -0,0 +1,93 @@ +/* + * This file is a part of project QuickShop, the name is Timer.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@EqualsAndHashCode +@ToString +public class Timer { + private long startTime; + + /** + * Create a empty time, use setTimer to start + */ + public Timer() { + } + + /** + * Create a empty time, auto start if autoSet is true + * + * @param autoSet Auto set the timer + */ + public Timer(boolean autoSet) { + if (autoSet) { + startTime = System.currentTimeMillis(); + } + } + + /** + * Create a empty time, use the param to init the startTime. + * + * @param startTime New startTime + */ + public Timer(long startTime) { + this.startTime = startTime; + } + + /** + * Return how long time running when timer set and destory the timer. + * + * @return time + */ + public long endTimer() { + long time = System.currentTimeMillis() - startTime; + startTime = 0; + return time; + } + + /** + * Return how long time running after atTimeS. THIS NOT WILL DESTORY AND STOP THE TIMER + * + * @param atTime The inited time + * @return time + */ + public long getTimerAt(long atTime) { + return atTime - startTime; + } + + /** + * Create a Timer. Time Unit: ms + */ + public void setTimer() { + this.startTime = System.currentTimeMillis(); + } + + /** + * Return how long time running when timer set. THIS NOT WILL DESTORY AND STOP THE TIMER + * + * @return time + */ + public long getTimer() { + return System.currentTimeMillis() - startTime; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/UpdateInfomation.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/UpdateInfomation.java new file mode 100644 index 0000000..649b3a8 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/UpdateInfomation.java @@ -0,0 +1,38 @@ +/* + * This file is a part of project QuickShop, the name is UpdateInfomation.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.jetbrains.annotations.Nullable; + +@AllArgsConstructor +@ToString +@Data +@EqualsAndHashCode +public class UpdateInfomation { + private boolean isBeta; + + @Nullable + private String version; + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Updater.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Updater.java new file mode 100644 index 0000000..3cca349 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Updater.java @@ -0,0 +1,148 @@ +/* + * This file is a part of project QuickShop, the name is Updater.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import org.abc.A.util.github.GithubAPI; +import org.abc.A.util.github.ReleaseJsonContainer; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.plugin.InvalidDescriptionException; +import org.bukkit.plugin.PluginDescriptionFile; +import org.jetbrains.annotations.Nullable; +import org.abc.A.L.com.sk89q.worldedit.util.net.HttpRequest; +import org.abc.A.QuickShop; + +import java.io.*; +import java.net.URL; +import java.util.Objects; + +public class Updater { + /** + * Check new update + * + * @return True=Have a new update; False=No new update or check update failed. + */ + public static UpdateInfomation checkUpdate() { + if (true) { + return new UpdateInfomation(false, null); + } + try { + + String localPluginVersion = QuickShop.instance.getDescription().getVersion(); + String spigotPluginVersion = + HttpRequest.get(new URL("https://api.spigotmc.org/legacy/update.php?resource=62575")) + .execute() + .expectResponseCode(200) + .returnContent() + .asString("UTF-8") + .trim(); + if (!spigotPluginVersion.isEmpty() && !spigotPluginVersion.equals(localPluginVersion)) { + Util.debugLog(spigotPluginVersion); + return new UpdateInfomation( + spigotPluginVersion.toLowerCase().contains("beta"), spigotPluginVersion); + } + return new UpdateInfomation(false, spigotPluginVersion); + } catch (IOException e) { + MsgUtil.sendMessage(Bukkit.getConsoleSender(), + ChatColor.RED + + "[QuickShop] Failed to check for an update on SpigotMC.org! It might be an internet issue or the SpigotMC host is down. If you want disable the update checker, you can disable in config.yml, but we still high-recommend check for updates on SpigotMC.org often."); + return new UpdateInfomation(false, null); + } + } + + public static byte[] downloadUpdatedJar() throws IOException { + @Nullable String uurl; + long uurlSize; + try { + ReleaseJsonContainer.AssetsBean bean = + Objects.requireNonNull(new GithubAPI().getLatestRelease()); + uurl = bean.getBrowser_download_url(); + uurlSize = bean.getSize(); + } catch (Throwable ig) { + throw new IOException(ig.getMessage()); + } + + if (uurl == null) { + throw new IOException("Failed read the URL, cause it is empty."); + } + QuickShop.instance.getLogger().info("Downloading from " + uurl); + InputStream is = + HttpRequest.get(new URL(uurl)) + .header("User-Agent", "QuickShop-Reremake " + QuickShop.getVersion()) + .execute() + .getInputStream(); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + byte[] buff = new byte[1024]; + int len; + long downloaded = 0; + if (is == null) { + throw new IOException("Failed downloading: Cannot open connection with remote server."); + } + while ((len = is.read(buff)) != -1) { + os.write(buff, 0, len); + downloaded += len; + Util.debugLog("File Downloader: " + downloaded + "/" + uurlSize + " bytes."); + } + Util.debugLog("Downloaded: " + downloaded + " Server:" + uurlSize); + if (!(uurlSize < 1) && downloaded != uurlSize) { + Util.debugLog("Size not match, download may broken."); + QuickShop.instance.getLogger().info("Failed to download update: Size not match, downloaded: " + downloaded + " excepted: " + uurlSize); + throw new IOException("Size not match, download mayb broken, aborting."); + } + Util.debugLog("Download complete."); + return os.toByteArray(); + } + + public static void replaceTheJar(byte[] data) throws RuntimeException, IOException { + File pluginFolder = new File("plugins"); + if (!pluginFolder.exists()) { + throw new RuntimeException("Can't find the plugins folder."); + } + if (!pluginFolder.isDirectory()) { + throw new RuntimeException("Plugins not a folder."); + } + File[] plugins = pluginFolder.listFiles(); + if (plugins == null) { + throw new IOException("Can't get the files in plugins folder"); + } + File quickshop = null; + for (File plugin : plugins) { + try { + PluginDescriptionFile desc = + QuickShop.instance.getPluginLoader().getPluginDescription(plugin); + if (!desc.getName().equals(QuickShop.instance.getDescription().getName())) { + continue; + } + Util.debugLog("Selected: " + plugin.getPath()); + quickshop = plugin; + break; + } catch (InvalidDescriptionException e) { // Ignore } + } + } + if (quickshop == null) { + throw new RuntimeException("Failed to get QuickShop Jar File."); + } + OutputStream outputStream = new FileOutputStream(quickshop, false); + outputStream.write(data); + outputStream.flush(); + outputStream.close(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Util.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Util.java new file mode 100644 index 0000000..5d5185f --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/Util.java @@ -0,0 +1,1407 @@ +/* + * This file is a part of project QuickShop, the name is Util.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import com.google.common.io.Files; +import lombok.NonNull; +import org.bukkit.*; +import org.bukkit.block.*; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.inventory.DoubleChestInventory; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.Damageable; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.QuickShop; +import org.abc.A.E.MySQLCore; +import org.abc.A.N.DisplayItem; +import org.abc.A.N.Shop; +import org.abc.A.O.InventoryEditContainer; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; + +import java.io.*; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.text.DecimalFormat; +import java.util.AbstractMap.SimpleEntry; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * @author MACHENIKE + */ + +public class Util { + private static final EnumSet blacklist = EnumSet.noneOf(Material.class); + + private static final EnumMap> restrictedPrices = + new EnumMap<>(Material.class); + + private static final EnumSet shoppables = EnumSet.noneOf(Material.class); + + static short tookLongTimeCostTimes; + + private static List debugLogs = new LinkedList<>(); + private static ReentrantReadWriteLock lock=new ReentrantReadWriteLock(); + + private static boolean devMode = false; + + private static QuickShop plugin; + + private static Object serverInstance; + + private static Field tpsField; + + private static List worldBlacklist = new ArrayList<>(); + + private static final List verticalFacing = Collections.unmodifiableList(Arrays.asList(BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST)); + + private static boolean disableDebugLogger = false; + + /** + * Convert strArray to String. E.g "Foo, Bar" + * + * @param strArray Target array + * @return str + */ + public static String array2String(@NotNull String[] strArray) { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < strArray.length; i++) { + builder.append(strArray[i]); + if (i + 1 != strArray.length) { + builder.append(", "); + } + } + return builder.toString(); + } + + /** + * Backup shops.db + * + * @return The result for backup + */ + public static boolean backupDatabase() { + if (plugin.getDatabase().getCore() instanceof MySQLCore) { + return true; // Backup and logs by MySQL + } + File dataFolder = plugin.getDataFolder(); + File sqlfile = new File(dataFolder, "shops.db"); + if (!sqlfile.exists()) { + plugin.getLogger().warning("Failed to backup! (File not found)"); + return false; + } + String uuid = UUID.randomUUID().toString().replaceAll("_", ""); + File bksqlfile = new File(dataFolder, "/shops_backup_" + uuid + ".db"); + try { + Files.copy(sqlfile, bksqlfile); + } catch (Exception e1) { + e1.printStackTrace(); + plugin.getLogger().warning("Failed to backup the database."); + return false; + } + return true; + } + + /** + * Returns true if the given block could be used to make a shop out of. + * + * @param b The block to check, Possibly a chest, dispenser, etc. + * @return True if it can be made into a shop, otherwise false. + */ + public static boolean canBeShop(@NotNull Block b) { + BlockState bs = b.getState(); + + // Specificed types by configuration + if (!isShoppables(b.getType())) { + return false; + } + + if (isBlacklistWorld(b.getWorld())) { + return false; + } + + if (bs instanceof EnderChest) { // BlockState for Mod supporting + return plugin.getOpenInvPlugin() != null; + } + + return bs instanceof InventoryHolder; + } + + /** + * Check a material is possible become a shop + * + * @param material Mat + * @return Can or not + */ + public static boolean isShoppables(@NotNull Material material) { + return shoppables.contains(material); + } + + public static boolean isBlacklistWorld(@NotNull World world) { + return worldBlacklist.contains(world.getName()); + } + + /** + * Counts the number of items in the given inventory where Util.matches(inventory item, item) is + * true. + * + * @param inv The inventory to search + * @param item The ItemStack to search for + * @return The number of items that match in this inventory. + */ + public static int countItems(@Nullable Inventory inv, @NotNull ItemStack item) { + if (inv == null) { + return 0; + } + int items = 0; + for (ItemStack iStack : inv.getStorageContents()) { + //noinspection ConstantConditions + if (iStack == null || iStack.getType() == Material.AIR) { + continue; + } + if (plugin.getItemMatcher().matches(item, iStack)) { + items += iStack.getAmount(); + } + } + return items; + } + + /** + * Returns the number of items that can be given to the inventory safely. + * + * @param inv The inventory to count + * @param item The item prototype. Material, durabiltiy and enchants must match for 'stackability' + * to occur. + * @return The number of items that can be given to the inventory safely. + */ + public static int countSpace(@Nullable Inventory inv, @NotNull ItemStack item) { + if (inv == null) { + return 0; + } + int space = 0; + + ItemStack[] contents = inv.getStorageContents(); + for (ItemStack iStack : contents) { + if (iStack == null || iStack.getType() == Material.AIR) { + space += item.getMaxStackSize(); + } else if (plugin.getItemMatcher().matches(item, iStack)) { + space += item.getMaxStackSize() - iStack.getAmount(); + } + } + return space; + } + + /** + * Covert YAML string to ItemStack. + * + * @param config serialized ItemStack + * @return ItemStack iStack + * @throws InvalidConfigurationException when failed deserialize config + */ + @Nullable + public static ItemStack deserialize(@NotNull String config) throws InvalidConfigurationException { + DumperOptions yamlOptions = new DumperOptions(); + yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + yamlOptions.setIndent(2); + Yaml yaml = new Yaml(yamlOptions); + YamlConfiguration yamlConfiguration = new YamlConfiguration(); + Map root = yaml.load(config); + //noinspection unchecked + Map item = (Map) root.get("item"); + int itemDataVersion = Integer.parseInt(String.valueOf(item.get("v"))); + try { + // Try load the itemDataVersion to do some checks. + //noinspection deprecation + if (itemDataVersion > Bukkit.getUnsafe().getDataVersion()) { + Util.debugLog("WARNING: DataVersion not matched with ItemStack: " + config); + // okay we need some things to do + if (plugin.getConfig().getBoolean("shop.force-load-downgrade-items.enable")) { + // okay it enabled + Util.debugLog("QuickShop is trying force loading " + config); + if (plugin.getConfig().getInt("shop.force-load-downgrade-items.method") == 0) { // Mode 0 + //noinspection deprecation + item.put("v", Bukkit.getUnsafe().getDataVersion() - 1); + } else { // Mode other + //noinspection deprecation + item.put("v", Bukkit.getUnsafe().getDataVersion()); + } + // Okay we have hacked the dataVersion, now put it back + root.put("item", item); + config = yaml.dump(root); + + Util.debugLog("Updated, we will try load as hacked ItemStack: " + config); + } else { + plugin + .getLogger() + .warning( + "Cannot load ItemStack " + + config + + " because it saved from higher Minecraft server version, the action will fail and you will receive a exception, PLELASE DON'T REPORT TO QUICKSHOP!"); + plugin + .getLogger() + .warning( + "You can try force load this ItemStack by our hacked ItemStack read util(shop.force-load-downgrade-items), but beware, the data may damaged if you load on this lower Minecraft server version, Please backup your world and database before enable!"); + } + } + yamlConfiguration.loadFromString(config); + return yamlConfiguration.getItemStack("item"); + } catch (Exception e) { + e.printStackTrace(); + yamlConfiguration.loadFromString(config); + return yamlConfiguration.getItemStack("item"); + } + } + + public static List getDebugLogs() { + lock.readLock().lock(); + List strings=new ArrayList<>(debugLogs); + lock.readLock().unlock(); + return strings; + } + + /** + * Print debug log when plugin running on dev mode. + * + * @param logs logs + */ + public static void debugLog(@NotNull String... logs) { + if(disableDebugLogger){ + return; + } + lock.writeLock().lock(); + if(debugLogs.size()>=2000){ + debugLogs.clear(); + } + if (!devMode) { + for (String log : logs) { + debugLogs.add("[DEBUG] " + log); + } + lock.writeLock().unlock(); + return; + } + StackTraceElement stackTraceElement = new Throwable().getStackTrace()[1]; + String className = stackTraceElement.getClassName(); + String methodName = stackTraceElement.getMethodName(); + int codeLine = stackTraceElement.getLineNumber(); + for (String log : logs) { + debugLogs.add("[DEBUG] [" + className + "] [" + methodName + "] (" + codeLine + ") " + log); + QuickShop.instance.getLogger().info("[DEBUG] [" + className + "] [" + methodName + "] (" + codeLine + ") " + log); + } + lock.writeLock().unlock(); + } + + /** + * Formats the given number according to how vault would like it. E.g. $50 or 5 dollars. + * + * @param n price + * @return The formatted string. + */ + public static String format(double n) { + if (plugin.getConfig().getBoolean("shop.disable-vault-format")) { + return plugin.getConfig().getString("shop.alternate-currency-symbol") + n; + } + try { + String formated = plugin.getEconomy().format(n); + if (formated == null || formated.isEmpty()) { + Util.debugLog( + "Use alternate-currency-symbol to formatting, Cause economy plugin returned null"); + return plugin.getConfig().getString("shop.alternate-currency-symbol") + n; + } else { + return formated; + } + } catch (NumberFormatException e) { + Util.debugLog("format", e.getMessage()); + Util.debugLog( + "format", "Use alternate-currency-symbol to formatting, Cause NumberFormatException"); + return plugin.getConfig().getString("shop.alternate-currency-symbol") + n; + } + } + + + /** + * return the right side for given blockFace + * + * @param blockFace given blockFace + * @return the right side for given blockFace, UP and DOWN will return itself + */ + public static BlockFace getRightSide(@NonNull BlockFace blockFace) { + switch (blockFace) { + case EAST: + return BlockFace.SOUTH; + case NORTH: + return BlockFace.EAST; + case SOUTH: + return BlockFace.WEST; + case WEST: + return BlockFace.NORTH; + default: + return blockFace; + } + } + + + /** + * Get vertical BlockFace list + * + * @return vertical BlockFace list (unmodifiable) + */ + public static List getVerticalFacing() { + return verticalFacing; + } + + /** + * Fetches the block which the given sign is attached to + * + * @param b The block which is attached + * @return The block the sign is attached to + */ + @Nullable + public static Block getAttached(@NotNull Block b) { + BlockData blockData = b.getBlockData(); + if (blockData instanceof Directional) { + Directional directional = (Directional) blockData; + return b.getRelative(directional.getFacing().getOppositeFace()); + } else { + return null; + } + } + + /** + * Return the Class name. + * + * @param c The class to get name + * @return The class prefix + */ + public static String getClassPrefix(@NotNull Class c) { + String callClassName = Thread.currentThread().getStackTrace()[2].getClassName(); + String customClassName = c.getSimpleName(); + return "[" + callClassName + "-" + customClassName + "] "; + } + + public static String getItemStackName(@NotNull ItemStack itemStack) { + if (itemStack.hasItemMeta() + && Objects.requireNonNull(itemStack.getItemMeta()).hasDisplayName()) { + return itemStack.getItemMeta().getDisplayName(); + } + return MsgUtil.getItemi18n(itemStack.getType().name()); + } + + /** + * Get ItemStack's local name, return null if failed to get. + * + * @param itemStack Target ItemStack + * @return LocalName or NULL + */ + @Nullable + public static String getLocalizedName(@NotNull ItemStack itemStack) { + ItemMeta itemMeta = itemStack.getItemMeta(); + if (itemMeta == null) { + return null; + } + if (!itemMeta.hasLocalizedName()) { + return null; + } + return itemMeta.getLocalizedName(); + } + + /** + * @param iStack itemstack + * @return potion data, readable + */ + @Nullable + public static String getPotiondata(@NotNull ItemStack iStack) { + if ((iStack.getType() != Material.POTION) + && (iStack.getType() != Material.LINGERING_POTION) + && (iStack.getType() != Material.SPLASH_POTION)) { + return null; + } + if (!(iStack.getItemMeta() instanceof PotionMeta)) { + return null; + } + List pEffects = new ArrayList<>(); + PotionMeta pMeta = (PotionMeta) iStack.getItemMeta(); + // if (pMeta.getBasePotionData().getType() != null) { + if (!(pMeta.getBasePotionData().isUpgraded())) { + pEffects.add( + ChatColor.BLUE + + MsgUtil.getPotioni18n( + Objects.requireNonNull(pMeta.getBasePotionData().getType().getEffectType()))); + } else { + pEffects.add( + ChatColor.BLUE + + MsgUtil.getPotioni18n( + Objects.requireNonNull(pMeta.getBasePotionData().getType().getEffectType())) + + " II"); + } + + // } + if (pMeta.hasCustomEffects()) { + List cEffects = pMeta.getCustomEffects(); + for (PotionEffect potionEffect : cEffects) { + pEffects.add( + MsgUtil.getPotioni18n(potionEffect.getType()) + + " " + + RomanNumber.toRoman(potionEffect.getAmplifier())); + } + } + if (!pEffects.isEmpty()) { + StringBuilder result = new StringBuilder(); + for (String effectString : pEffects) { + result.append(effectString); + result.append("\n"); + } + return result.toString(); + } else { + return null; + } + } + + /** + * Return an entry with min and max prices, but null if there isn't a price restriction + * + * @param material mat + * @return min, max + */ + public static Entry getPriceRestriction(@NotNull Material material) { + return restrictedPrices.get(material); + } + + /** + * Returns the chest attached to the given chest. The given block must be a chest. + * + * @param b he chest to check. + * @return the block which is also a chest and connected to b. + * @deprecated + */ + @Nullable + @Deprecated + public static Block getSecondHalf_old(@NotNull Block b) { + // if (b.getType() != Material.CHEST && b.getType() != Material.TRAPPED_CHEST) + // // return null; + if (!isDoubleChest(b)) { + return null; + } + Block[] blocks = new Block[4]; + blocks[0] = b.getRelative(1, 0, 0); + blocks[1] = b.getRelative(-1, 0, 0); + blocks[2] = b.getRelative(0, 0, 1); + blocks[3] = b.getRelative(0, 0, -1); + for (Block c : blocks) { + if (c.getType() == b.getType()) { + return c; + } + } + return null; + } + + public static boolean isDoubleChest(@Nullable Block b) { + if (b == null) { + return false; + } + if (!(b.getState() instanceof Container)) { + return false; + } + Container container = (Container) b.getState(); + return (container.getInventory() instanceof DoubleChestInventory); + } + + /** + * Get how many shop in the target world. + * + * @param worldName Target world. + * @return The shops. + */ + public static int getShopsInWorld(@NotNull String worldName) { + int cost = 0; + Iterator iterator = plugin.getShopManager().getShopIterator(); + while (iterator.hasNext()) { + Shop shop = iterator.next(); + if (Objects.requireNonNull(shop.getLocation().getWorld()).getName().equals(worldName)) { + cost++; + } + } + return cost; + } + + /** + * Gets the percentage (Without trailing %) damage on a tool. + * + * @param item The ItemStack of tools to check + * @return The percentage 'health' the tool has. (Opposite of total damage) + */ + public static String getToolPercentage(@NotNull ItemStack item) { + if (!(item.getItemMeta() instanceof Damageable)) { + Util.debugLog(item.getType().name() + " not Damageable."); + return "Error: NaN"; + } + double dura = ((Damageable) item.getItemMeta()).getDamage(); + double max = item.getType().getMaxDurability(); + DecimalFormat formatter = new DecimalFormat("0"); + return formatter.format((1 - dura / max) * 100.0); + } + + /** + * Use yaw to calc the BlockFace + * + * @param yaw Yaw (Player.getLocation().getYaw()) + * @return BlockFace blockFace + * @deprecated Use Bukkit util not this one. + */ + @Deprecated + public static BlockFace getYawFace(float yaw) { + if (yaw > 315 && yaw <= 45) { + return BlockFace.NORTH; + } else if (yaw > 45 && yaw <= 135) { + return BlockFace.EAST; + } else if (yaw > 135 && yaw <= 225) { + return BlockFace.SOUTH; + } else { + return BlockFace.WEST; + } + } + + /** + * Initialize the Util tools. + */ + public static void initialize() { + blacklist.clear(); + shoppables.clear(); + restrictedPrices.clear(); + worldBlacklist.clear(); + plugin = QuickShop.instance; + devMode = plugin.getConfig().getBoolean("dev-mode"); + + for (String s : plugin.getConfig().getStringList("shop-blocks")) { + Material mat = Material.matchMaterial(s.toUpperCase()); + if (mat == null) { + mat = Material.matchMaterial(s); + } + if (mat == null) { + plugin.getLogger().warning("Invalid shop-block: " + s); + } else { + shoppables.add(mat); + } + } + List configBlacklist = plugin.getConfig().getStringList("blacklist"); + for (String s : configBlacklist) { + Material mat = Material.getMaterial(s.toUpperCase()); + if (mat == null) { + mat = Material.matchMaterial(s); + } + if (mat == null) { + plugin.getLogger().warning(s + " is not a valid material. Check your spelling or ID"); + continue; + } + blacklist.add(mat); + } + + for (String s : plugin.getConfig().getStringList("shop.price-restriction")) { + String[] sp = s.split(";"); + if (sp.length == 3) { + try { + Material mat = Material.matchMaterial(sp[0]); + if (mat == null) { + plugin + .getLogger() + .warning( + "Material " + + sp[0] + + " in config.yml can't match with a valid Materials, check your config.yml!"); + continue; + } + restrictedPrices.put( + mat, new SimpleEntry<>(Double.valueOf(sp[1]), Double.valueOf(sp[2]))); + } catch (Exception e) { + plugin.getLogger().warning("Invalid price restricted material: " + s); + } + } + } + worldBlacklist = plugin.getConfig().getStringList("shop.blacklist-world"); + disableDebugLogger = plugin.getConfig().getBoolean("disable-debuglogger", false); + } + + /** + * Read the InputStream to the byte array. + * + * @param filePath Target file + * @return Byte array + */ + @Nullable + public static byte[] inputStream2ByteArray(@NotNull String filePath) { + try { + InputStream in = new FileInputStream(filePath); + byte[] data = toByteArray(in); + in.close(); + return data; + } catch (IOException e) { + return null; + } + } + + private static byte[] toByteArray(@NotNull InputStream in) throws IOException { + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024 * 4]; + int n; + while ((n = in.read(buffer)) != -1) { + out.write(buffer, 0, n); + } + return out.toByteArray(); + } + + /** + * Read the InputStream to the byte array. + * + * @param inputStream Target stream + * @return Byte array + */ + @Nullable + public static byte[] inputStream2ByteArray(@NotNull InputStream inputStream) { + try { + byte[] data = toByteArray(inputStream); + inputStream.close(); + return data; + } catch (IOException e) { + return null; + } + } + + /** + * Call this to check items in inventory and remove it. + * + * @param inv inv + */ + public static void inventoryCheck(@Nullable Inventory inv) { + if (inv == null) { + return; + } + if (inv.getHolder() == null) { + Util.debugLog("Skipped plugin gui inventory check."); + return; + } + new BukkitRunnable() { + @Override + public void run() { + try { + for (int i = 0; i < inv.getSize(); i++) { + ItemStack itemStack = inv.getItem(i); + if (itemStack == null) { + continue; + } + if (DisplayItem.checkIsGuardItemStack(itemStack)) { + // Found Item and remove it. + Location location = inv.getLocation(); + if (location == null) { + return; // Virtual GUI + } + plugin + .getSyncTaskWatcher() + .getInventoryEditQueue() + .offer(new InventoryEditContainer(inv, i, new ItemStack(Material.AIR))); + Util.debugLog("Found a displayitem in an inventory, Scheduling to removal..."); + MsgUtil.sendGlobalAlert( + "[InventoryCheck] Found displayItem in inventory at " + + location + + ", Item is " + + itemStack.getType().name()); + } + } + } catch (Throwable t) { + // Ignore + } + } + }.runTaskAsynchronously(plugin); + } + + /** + * @param stack The ItemStack to check if it is blacklisted + * @return true if the ItemStack is black listed. False if not. + */ + public static boolean isBlacklisted(@NotNull ItemStack stack) { + if (blacklist.contains(stack.getType())) { + return true; + } + if (!stack.hasItemMeta()) { + return false; + } + if (!Objects.requireNonNull(stack.getItemMeta()).hasLore()) { + return false; + } + for (String lore : Objects.requireNonNull(stack.getItemMeta().getLore())) { + List blacklistLores = plugin.getConfig().getStringList("shop.blacklist-lores"); + for (String blacklistLore : blacklistLores) { + if (lore.contains(blacklistLore)) { + return true; + } + } + } + return false; + } + + /** + * Get this class available or not + * + * @param qualifiedName class qualifiedName + * @return boolean Available + */ + public static boolean isClassAvailable(@NotNull String qualifiedName) { + try { + Class.forName(qualifiedName); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + + public static boolean isDisplayAllowBlock(@NotNull Material mat) { + if (isAir(mat)) { + return true; + } + return isWallSign(mat); + } + + public static boolean isAir(@NotNull Material mat) { + if (mat == Material.AIR) { + return true; + } + /* For 1.13 new AIR */ + try { + if (mat == Material.CAVE_AIR) { + return true; + } + if (mat == Material.VOID_AIR) { + return true; + } + } catch (Throwable t) { + // ignore + } + return false; + } + + /** + * Check a material is or not a WALL_SIGN + * + * @param material mat + * @return is or not a wall_sign + */ + public static boolean isWallSign(@Nullable Material material) { + if (material == null) { + return false; + } + try { + return Tag.WALL_SIGNS.isTagged(material); + } catch (NoSuchFieldError e) { + return "WALL_SIGN".equals(material.name()); + } + } + + /** + * Returns true if the given location is loaded or not. + * + * @param loc The location + * @return true if the given location is loaded or not. + */ + public static boolean isLoaded(@NotNull Location loc) { + // plugin.getLogger().log(Level.WARNING, "Checking isLoaded(Location loc)"); + if (loc.getWorld() == null) { + // plugin.getLogger().log(Level.WARNING, "Is not loaded. (No world)"); + return false; + } + // Calculate the chunks coordinates. These are 1,2,3 for each chunk, NOT + // location rounded to the nearest 16. + int x = (int) Math.floor((loc.getBlockX()) / 16.0); + int z = (int) Math.floor((loc.getBlockZ()) / 16.0); + return (loc.getWorld().isChunkLoaded(x, z)); + } + + /** + * Checks whether someone else's shop is within reach of a hopper being placed by a player. + * + * @param b The block being placed. + * @param p The player performing the action. + * @return true if a nearby shop was found, false otherwise. + */ + public static boolean isOtherShopWithinHopperReach(@NotNull Block b, @NotNull Player p) { + // Check 5 relative positions that can be affected by a hopper: behind, in front of, to the + // right, + // to the left and underneath. + Block[] blocks = new Block[5]; + blocks[0] = b.getRelative(0, 0, -1); + blocks[1] = b.getRelative(0, 0, 1); + blocks[2] = b.getRelative(1, 0, 0); + blocks[3] = b.getRelative(-1, 0, 0); + blocks[4] = b.getRelative(0, 1, 0); + for (Block c : blocks) { + Shop firstShop = plugin.getShopManager().getShop(c.getLocation()); + // If firstShop is null but is container, it can be used to drain contents from a shop created + // on secondHalf. + Block secondHalf = getSecondHalf(c); + Shop secondShop = + secondHalf == null ? null : plugin.getShopManager().getShop(secondHalf.getLocation()); + if (firstShop != null && !p.getUniqueId().equals(firstShop.getOwner()) + || secondShop != null && !p.getUniqueId().equals(secondShop.getOwner())) { + return true; + } + } + return false; + } + + /** + * Returns the chest attached to the given chest. The given block must be a chest. + * + * @param b The chest to check. + * @return the block which is also a chest and connected to b. + */ + @Nullable + public static Block getSecondHalf(@NotNull Block b) { + BlockState state = b.getState(); + if (!(state instanceof Chest)) { + return null; + } + Chest oneSideOfChest = (Chest) state; + InventoryHolder chestHolder = oneSideOfChest.getInventory().getHolder(); + if (chestHolder instanceof DoubleChest) { + DoubleChest doubleChest = (DoubleChest) chestHolder; + InventoryHolder left = doubleChest.getLeftSide(); + InventoryHolder right = doubleChest.getRightSide(); + Chest leftC = (Chest) left; + Chest rightC = (Chest) right; + if (equalsBlockStateLocation(oneSideOfChest.getLocation(), Objects.requireNonNull(rightC).getLocation())) { + return Objects.requireNonNull(leftC).getBlock(); + } + if (equalsBlockStateLocation(oneSideOfChest.getLocation(), Objects.requireNonNull(leftC).getLocation())) { + return rightC.getBlock(); + } + } + return null; + } + + /** + * Check two location is or not equals for the BlockPosition on 2D + * + * @param b1 block 1 + * @param b2 block 2 + * @return Equals or not. + */ + private static boolean equalsBlockStateLocation(@NotNull Location b1, @NotNull Location b2) { + return (b1.getBlockX() == b2.getBlockX()) + && (b1.getBlockY() == b2.getBlockY()) + && (b1.getBlockZ() == b2.getBlockZ()); + } + + /** + * @param mat The material to check + * @return Returns true if the item is a tool (Has durability) or false if it doesn't. + */ + public static boolean isTool(@NotNull Material mat) { + return !(mat.getMaxDurability() == 0); + } + + /** + * Check a string is or not a UUID string + * + * @param string Target string + * @return is UUID + */ + public static boolean isUUID(@NotNull String string) { + if (string.length() != 36 && string.length() != 32) { + return false; + } + try { + //noinspection ResultOfMethodCallIgnored + UUID.fromString(string); + return true; + } catch (IllegalArgumentException e) { + return false; + } + } + + /** + * Convert strList to String. E.g "Foo, Bar" + * + * @param strList Target list + * @return str + */ + public static String list2String(@NotNull List strList) { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < strList.size(); i++) { + builder.append(strList.get(i)); + if (i + 1 != strList.size()) { + builder.append(", "); + } + } + return builder.toString(); + } + + /** + * Returns loc with modified pitch/yaw angles so it faces lookat + * + * @param loc The location a players head is + * @param lookat The location they should be looking + * @return The location the player should be facing to have their crosshairs on the location + * lookAt Kudos to bergerkiller for most of this function + */ + public static Location lookAt(Location loc, Location lookat) { + // Clone the loc to prevent applied changes to the input loc + loc = loc.clone(); + // Values of change in distance (make it relative) + double dx = lookat.getX() - loc.getX(); + double dy = lookat.getY() - loc.getY(); + double dz = lookat.getZ() - loc.getZ(); + // Set yaw + if (dx != 0) { + // Set yaw start value based on dx + if (dx < 0) { + loc.setYaw((float) (1.5 * Math.PI)); + } else { + loc.setYaw((float) (0.5 * Math.PI)); + } + loc.setYaw(loc.getYaw() - (float) Math.atan(dz / dx)); + } else if (dz < 0) { + loc.setYaw((float) Math.PI); + } + // Get the distance from dx/dz + double dxz = Math.sqrt(Math.pow(dx, 2) + Math.pow(dz, 2)); + float pitch = (float) -Math.atan(dy / dxz); + // Set values, convert to degrees + // Minecraft yaw (vertical) angles are inverted (negative) + loc.setYaw(-loc.getYaw() * 180f / (float) Math.PI + 360); + // But pitch angles are normal + loc.setPitch(pitch * 180f / (float) Math.PI); + return loc; + } + + /** + * Match the both map1 and map2 + * + * @param map1 Map1 + * @param map2 Map2 + * @return Map1 match Map2 and Map2 match Map1 + */ + @Deprecated + public static boolean mapDuoMatches(@NotNull Map map1, @NotNull Map map2) { + boolean result = mapMatches(map1, map2); + if (!result) { + return false; + } + return mapMatches(map2, map1); + } + + /** + * Match the map1 and map2 + * + * @param map1 Map1 + * @param map2 Map2 + * @return Map1 match Map2 + */ + public static boolean mapMatches(@NotNull Map map1, @NotNull Map map2) { + for (Object obj : map1.keySet()) { + if (!map2.containsKey(obj)) { + return false; + } + if (map1.get(obj) != map2.get(obj)) { + return false; + } + } + return true; + } + + /** + * Match the list1 and list2 + * + * @param list1 requireList + * @param list2 givenList + * @return Map1 match Map2 + */ + public static boolean listMatches(@NotNull List list1, @NotNull List list2) { + return list2.containsAll(list1); + } + + /** + * Parse colors for the YamlConfiguration. + * + * @param config yaml config + */ + public static void parseColours(@NotNull YamlConfiguration config) { + Set keys = config.getKeys(true); + for (String key : keys) { + String filtered = config.getString(key); + if (filtered == null) { + continue; + } + if (filtered.startsWith("MemorySection")) { + continue; + } + filtered = parseColours(filtered); + config.set(key, filtered); + } + } + + /** + * Parse colors for the Text. + * + * @param text the text + * @return parsed text + */ + public static String parseColours(@NotNull String text) { + text = ChatColor.translateAlternateColorCodes('&', text); + return text; + } + + /** + * Parse colors for the List. + * + * @param list the list + * @return parsed list + */ + public static List parseColours(@NotNull List list) { + final List newList = new ArrayList<>(); + + list.forEach(s -> newList.add(parseColours(s))); + + return newList; + } + + /** + * Converts a name like IRON_INGOT into Iron Ingot to improve readability + * + * @param ugly The string such as IRON_INGOT + * @return A nicer version, such as Iron Ingot + */ + public static String prettifyText(@NotNull String ugly) { + String[] nameParts = ugly.split("_"); + if (nameParts.length == 1) { + return firstUppercase(ugly); + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < nameParts.length; i++) { + sb.append(firstUppercase(nameParts[i])); + if (i + 1 != nameParts.length) { + sb.append(" "); + } + } + return sb.toString(); + } + + /** + * First uppercase for every words the first char for a text. + * + * @param string text + * @return Processed text. + */ + public static String firstUppercase(@NotNull String string) { + if (string.length() > 1) { + return Character.toUpperCase(string.charAt(0)) + string.substring(1).toLowerCase(); + } else { + return string.toUpperCase(); + } + } + + /** + * Read the file to the String + * + * @param fileName Target file. + * @return Target file's content. + */ + public static String readToString(@NotNull String fileName) { + File file = new File(fileName); + long filelength = file.length(); + byte[] filecontent = new byte[(int) filelength]; + try { + FileInputStream in = new FileInputStream(file); + in.read(filecontent); + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return new String(filecontent, StandardCharsets.UTF_8); + } + + /** + * Read the file to the String + * + * @param file Target file. + * @return Target file's content. + */ + public static String readToString(@NotNull File file) { + long filelength = file.length(); + byte[] filecontent = new byte[(int) filelength]; + try { + FileInputStream in = new FileInputStream(file); + in.read(filecontent); + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return new String(filecontent, StandardCharsets.UTF_8); + } + + /** + * Send warning message when some plugin calling deprecated method... With the trace. + */ + public static void sendDeprecatedMethodWarn() { + QuickShop.instance + .getLogger() + .warning( + "Some plugin is calling a Deprecated method, Please contact the author to tell them to use the new api!"); + StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); + for (StackTraceElement stackTraceElement : stackTraceElements) { + QuickShop.instance + .getLogger() + .warning( + "at " + + stackTraceElement.getClassName() + + "#" + + stackTraceElement.getMethodName() + + " (" + + stackTraceElement.getFileName() + + ":" + + stackTraceElement.getLineNumber() + + ")"); + } + } + + /** + * Covert ItemStack to YAML string. + * + * @param iStack target ItemStack + * @return String serialized itemStack + */ + public static String serialize(@NotNull ItemStack iStack) { + YamlConfiguration cfg = new YamlConfiguration(); + cfg.set("item", iStack); + return cfg.saveToString(); + } + + /** + * Return the Class name. + * + * @return The class prefix + */ + public static String getClassPrefix() { + + String className = Thread.currentThread().getStackTrace()[2].getClassName(); + try { + Class c = Class.forName(className); + className = c.getSimpleName(); + if (!c.getSimpleName().isEmpty()) { + className = c.getSimpleName(); + } + } catch (ClassNotFoundException e) { + // Ignore + } + String methodName = Thread.currentThread().getStackTrace()[2].getMethodName(); + return "[" + className + "-" + methodName + "] "; + } + + public static String getNMSVersion() { + String name = Bukkit.getServer().getClass().getPackage().getName(); + return name.substring(name.lastIndexOf('.') + 1); + } + + /** + * Get the sign material using by plugin. With compatiabily process. + * + * @return The material now using. + */ + public static Material getSignMaterial() { + + Material signMaterial = + Material.matchMaterial( + Objects.requireNonNull(plugin.getConfig().getString("shop.sign-material"))); + if (signMaterial != null) { + return signMaterial; + } + signMaterial = Material.matchMaterial("OAK_WALL_SIGN"); // Fallback default sign in 1.14 + if (signMaterial != null) { + return signMaterial; + } + signMaterial = Material.matchMaterial("WALL_SIGN"); // Fallback default sign in 1.13 + if (signMaterial != null) { + return signMaterial; + } + // What the fuck!? + plugin + .getLogger() + .warning( + "QuickShop can't found any useable sign material, we will use default Sign Material."); + try { + return Material.OAK_WALL_SIGN; + } catch (Throwable e) { + return Material.matchMaterial("WALL_SIGN"); + } + } + + /** + * Get MinecraftServer's TPS + * + * @return TPS (e.g 19.92) + */ + public static Double getTPS() { + if(serverInstance == null || tpsField == null) { + try { + serverInstance = getNMSClass("MinecraftServer").getMethod("getServer").invoke(null); + tpsField = serverInstance.getClass().getField("recentTps"); + } catch (NoSuchFieldException + | SecurityException + | IllegalAccessException + | IllegalArgumentException + | InvocationTargetException + | NoSuchMethodException e) { + e.printStackTrace(); + } + } + try { + double[] tps = ((double[]) tpsField.get(serverInstance)); + return tps[0]; + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + public static Class getNMSClass(@Nullable String className) { + if (className == null) { + className = "MinecraftServer"; + } + String name = Bukkit.getServer().getClass().getPackage().getName(); + String version = name.substring(name.lastIndexOf('.') + 1); + try { + return Class.forName("net.minecraft.server." + version + "." + className); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + // + // public static void shoppablesCheck(@NotNull Shop shop) { + // if (!Util.canBeShop(shop.getLocation().getBlock())) { + // Util.debugLog("This shopblock can't be a shop, deleting..."); + // shop.onUnload(); + // shop.delete(); + // } + // } + + /** + * Check QuickShop is running on dev edition or not. + * + * @return DevEdition status + */ + public static boolean isDevEdition() { + String version = QuickShop.instance.getDescription().getVersion().toLowerCase(); + return (version.contains("dev") + || version.contains("develop") + || version.contains("alpha") + || version.contains("beta") + || version.contains("test") + || version.contains("snapshot") + || version.contains("preview")); + } + + /** + * Get the plugin is under dev-mode(debug mode) + * + * @return under dev-mode + */ + public static boolean isDevMode() { + return devMode; + } + + /** + * Get a material is a dye + * + * @param material The material + * @return yes or not + */ + public static boolean isDyes(@NotNull Material material) { + return material.name().toUpperCase().endsWith("_DYE"); + } + + /** + * Calc the string md5 + * + * @param s string + * @return md5 + */ + @NotNull + public static String md5(final String s) { + try { + final MessageDigest instance = MessageDigest.getInstance("MD5"); + instance.update(s.getBytes(StandardCharsets.UTF_8)); + final byte[] digest = instance.digest(); + final StringBuilder sb = new StringBuilder(); + for (int b : digest) { + int n = b; + if (n < 0) { + n += 256; + } + if (n < 16) { + sb.append("0"); + } + sb.append(Integer.toHexString(n)); + } + return sb.toString().toLowerCase(); + } catch (Exception ex) { + return ""; + } + } + + /** + * Call a event and check it is cancelled. + * + * @param event The event implement the Cancellable interface. + * @return The event is cancelled. + */ + public static boolean fireCancellableEvent(@NotNull Cancellable event) { + if (!(event instanceof Event)) { + throw new IllegalArgumentException("Cancellable must is event implement"); + } + Bukkit.getPluginManager().callEvent((Event) event); + return event.isCancelled(); + } + + /** + * Get QuickShop caching folder + * + * @return The caching folder + */ + public static File getCacheFolder() { + File cache = new File(QuickShop.instance.getDataFolder(), "cache"); + if (!cache.exists()) { + cache.mkdirs(); + } + return cache; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/WarningSender.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/WarningSender.java new file mode 100644 index 0000000..742fdc8 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/WarningSender.java @@ -0,0 +1,63 @@ +/* + * This file is a part of project QuickShop, the name is WarningSender.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util; + +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.jetbrains.annotations.NotNull; +import org.abc.A.QuickShop; + +@EqualsAndHashCode +@ToString +public class WarningSender { + private long cooldown; + + private long lastSend = 0; + + @ToString.Exclude + private QuickShop plugin; + + /** + * Create a warning sender + * + * @param plugin Main class + * @param cooldown Time unit: ms + */ + public WarningSender(@NotNull QuickShop plugin, long cooldown) { + this.plugin = plugin; + this.cooldown = cooldown; + } + + /** + * Send warning a warning + * + * @param text The text you want send/ + * @return Success sent, if it is in a cool-down, it will return false + */ + public boolean sendWarn(String text) { + if (System.currentTimeMillis() - lastSend > cooldown) { + plugin.getLogger().warning(text); + this.lastSend = System.currentTimeMillis(); + return true; + } + return false; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/bukkitwrapper/BukkitAPIWrapper.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/bukkitwrapper/BukkitAPIWrapper.java new file mode 100644 index 0000000..84cf943 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/bukkitwrapper/BukkitAPIWrapper.java @@ -0,0 +1,48 @@ +/* + * This file is a part of project QuickShop, the name is BukkitAPIWrapper.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util.bukkitwrapper; + +import java.util.concurrent.CompletableFuture; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface BukkitAPIWrapper { + void teleportEntity( + @NotNull Entity entity, + @NotNull Location location, + @Nullable PlayerTeleportEvent.TeleportCause cause); + + void getChunkAt( + @NotNull World world, + @NotNull Location location, + @NotNull CompletableFuture futureTask); + + void getChunkAt(@NotNull World world, int x, int z, @NotNull CompletableFuture futureTask); + + void getChunkAt( + @NotNull World world, @NotNull Block block, @NotNull CompletableFuture futureTask); + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/bukkitwrapper/SpigotWrapper.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/bukkitwrapper/SpigotWrapper.java new file mode 100644 index 0000000..1ea35ac --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/bukkitwrapper/SpigotWrapper.java @@ -0,0 +1,65 @@ +/* + * This file is a part of project QuickShop, the name is SpigotWrapper.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util.bukkitwrapper; + +import java.util.concurrent.CompletableFuture; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class SpigotWrapper implements BukkitAPIWrapper { + @Override + public void teleportEntity( + @NotNull Entity entity, + @NotNull Location location, + @Nullable PlayerTeleportEvent.TeleportCause cause) { + if (cause == null) { + entity.teleport(location); + } else { + entity.teleport(location, cause); + } + } + + @Override + public void getChunkAt( + @NotNull World world, + @NotNull Location location, + @NotNull CompletableFuture futureTask) { + futureTask.complete(world.getChunkAt(location)); + } + + @Override + public void getChunkAt( + @NotNull World world, int x, int z, @NotNull CompletableFuture futureTask) { + futureTask.complete(world.getChunkAt(x, z)); + } + + @Override + public void getChunkAt( + @NotNull World world, @NotNull Block block, @NotNull CompletableFuture futureTask) { + futureTask.complete(world.getChunkAt(block)); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/compatibility/CompatibilityManager.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/compatibility/CompatibilityManager.java new file mode 100644 index 0000000..d7c6ba7 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/compatibility/CompatibilityManager.java @@ -0,0 +1,29 @@ +package org.abc.A.util.compatibility; + +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.Set; + +public class CompatibilityManager { + private Set registeredModules = new HashSet<>(); + + /** + * Switch the compatibility mode on or off, set false to disable all we known incompatiable plugin + * listener, set true to enable back all disabled plugin liseners. WIP + * + * @param status true=turn on closed listeners, false=turn off all turned on listeners. + * @param player The player to check the listeners + */ + public void toggleProtectionListeners(boolean status, @NotNull Player player) { + this.registeredModules.forEach(module->module.toggle(player,status)); + } + + public void register(@NotNull CompatibilityModule module){ + registeredModules.add(module); + } + public void unregister(@NotNull CompatibilityModule module){ + registeredModules.remove(module); + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/compatibility/CompatibilityModule.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/compatibility/CompatibilityModule.java new file mode 100644 index 0000000..9f1e145 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/compatibility/CompatibilityModule.java @@ -0,0 +1,26 @@ +package org.abc.A.util.compatibility; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +public interface CompatibilityModule { + /** + * Gets the CompatibilityModule provider name + * @return Provider name + */ + @NotNull String getName(); + + /** + * Gets the CompatibilityModule provider plugin instance + * @return Provider Plugin instance + */ + @NotNull Plugin getPlugin(); + + /** + * Calls CompatibilityModule to toggle the detection status for playerb between on and off + * @param player The player + * @param status On or Off + */ + void toggle(@NotNull Player player, boolean status); +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/compatibility/NCPCompatibilityModule.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/compatibility/NCPCompatibilityModule.java new file mode 100644 index 0000000..8db9388 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/compatibility/NCPCompatibilityModule.java @@ -0,0 +1,58 @@ +package org.abc.A.util.compatibility; + +import fr.neatmonster.nocheatplus.checks.CheckType; +import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager; +import lombok.AllArgsConstructor; +import org.abc.A.QuickShop; +import org.abc.A.util.Util; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +@AllArgsConstructor +public class NCPCompatibilityModule implements CompatibilityModule { + private QuickShop plugin; + /** + * Gets the CompatibilityModule provider name + * + * @return Provider name + */ + @Override + public @NotNull String getName() { + return "NoCheatPlus"; + } + + /** + * Gets the CompatibilityModule provider plugin instance + * + * @return Provider Plugin instance + */ + @Override + public @NotNull Plugin getPlugin() { + return plugin; + } + + /** + * Calls CompatibilityModule to toggle the detection status for playerb between on and off + * + * @param player The player + * @param status On or Off + */ + @Override + public void toggle(@NotNull Player player, boolean status) { + if(status){ + Util.debugLog( + "Calling NoCheatPlus ignore " + + player.getName() + + " cheats detection until we finished permission checks."); + + NCPExemptionManager.exemptPermanently(player, CheckType.BLOCKPLACE_REACH); + NCPExemptionManager.exemptPermanently(player, CheckType.BLOCKPLACE_FASTPLACE); + }else{ + Util.debugLog( + "Calling NoCheatPlus continue follow " + player.getName() + " cheats detection."); + NCPExemptionManager.unexempt(player, CheckType.BLOCKPLACE_REACH); + NCPExemptionManager.unexempt(player, CheckType.BLOCKPLACE_FASTPLACE); + } + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/github/GithubAPI.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/github/GithubAPI.java new file mode 100644 index 0000000..05a4afb --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/github/GithubAPI.java @@ -0,0 +1,62 @@ +/* + * This file is a part of project QuickShop, the name is GithubAPI.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util.github; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.net.URL; +import org.jetbrains.annotations.Nullable; +import org.abc.A.L.com.sk89q.worldedit.util.net.HttpRequest; + +public class GithubAPI { + private final Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + + @Nullable + public ReleaseJsonContainer.AssetsBean getLatestRelease() throws Exception { + String json = + HttpRequest.get( + new URL( + "https://api.github.com/repos/Ghost-chu/QuickShop-Reremake/releases/latest")) + .execute() + .returnContent() + .asString("UTF-8"); + ReleaseJsonContainer result = gson.fromJson(json, ReleaseJsonContainer.class); + for (ReleaseJsonContainer.AssetsBean asset : result.getAssets()) { + if (asset.getName().contains("original-")) { + continue; + } + if (asset.getName().contains("-javadoc")) { + continue; + } + if (asset.getName().contains("-sources")) { + continue; + } + if (asset.getName().contains("-shaded")) { + continue; + } + if (asset.getName().contains("Document") || asset.getName().contains("document")) { + continue; + } + return asset; + } + return null; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/github/ReleaseJsonContainer.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/github/ReleaseJsonContainer.java new file mode 100644 index 0000000..66f3b20 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/github/ReleaseJsonContainer.java @@ -0,0 +1,106 @@ +/* + * This file is a part of project QuickShop, the name is ReleaseJsonContainer.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util.github; + +import java.util.List; + +public class ReleaseJsonContainer { + /** + * url : https://api.github.com/repos/octocat/Hello-World/releases/1 html_url : + * https://github.com/octocat/Hello-World/releases/v1.0.0 assets_url : + * https://api.github.com/repos/octocat/Hello-World/releases/1/assets upload_url : + * https://uploads.github.com/repos/octocat/Hello-World/releases/1/assets{?name,label} tarball_url + * : https://api.github.com/repos/octocat/Hello-World/tarball/v1.0.0 zipball_url : + * https://api.github.com/repos/octocat/Hello-World/zipball/v1.0.0 id : 1 node_id : + * MDc6UmVsZWFzZTE= tag_name : v1.0.0 target_commitish : master name : v1.0.0 body : Description + * of the release draft : false prerelease : false created_at : 2013-02-27T19:35:32Z published_at + * : 2013-02-27T19:35:32Z author : + * {"login":"octocat","id":1,"node_id":"MDQ6VXNlcjE=","avatar_url":"https://github.com/images/error/octocat_happy.gif","gravatar_id":"","url":"https://api.github.com/users/octocat","html_url":"https://github.com/octocat","followers_url":"https://api.github.com/users/octocat/followers","following_url":"https://api.github.com/users/octocat/following{/other_user}","gists_url":"https://api.github.com/users/octocat/gists{/gist_id}","starred_url":"https://api.github.com/users/octocat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/octocat/subscriptions","organizations_url":"https://api.github.com/users/octocat/orgs","repos_url":"https://api.github.com/users/octocat/repos","events_url":"https://api.github.com/users/octocat/events{/privacy}","received_events_url":"https://api.github.com/users/octocat/received_events","type":"User","site_admin":false} + * assets : + * [{"url":"https://api.github.com/repos/octocat/Hello-World/releases/assets/1","browser_download_url":"https://github.com/octocat/Hello-World/releases/download/v1.0.0/example.zip","id":1,"node_id":"MDEyOlJlbGVhc2VBc3NldDE=","name":"example.zip","label":"short + * description","state":"uploaded","content_type":"application/zip","size":1024,"download_count":42,"created_at":"2013-02-27T19:35:32Z","updated_at":"2013-02-27T19:35:32Z","uploader":{"login":"octocat","id":1,"node_id":"MDQ6VXNlcjE=","avatar_url":"https://github.com/images/error/octocat_happy.gif","gravatar_id":"","url":"https://api.github.com/users/octocat","html_url":"https://github.com/octocat","followers_url":"https://api.github.com/users/octocat/followers","following_url":"https://api.github.com/users/octocat/following{/other_user}","gists_url":"https://api.github.com/users/octocat/gists{/gist_id}","starred_url":"https://api.github.com/users/octocat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/octocat/subscriptions","organizations_url":"https://api.github.com/users/octocat/orgs","repos_url":"https://api.github.com/users/octocat/repos","events_url":"https://api.github.com/users/octocat/events{/privacy}","received_events_url":"https://api.github.com/users/octocat/received_events","type":"User","site_admin":false}}] + */ + private int id; + + private String name; + + private List assets; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getAssets() { + return assets; + } + + public static class AssetsBean { + /** + * url : https://api.github.com/repos/octocat/Hello-World/releases/assets/1 browser_download_url + * : https://github.com/octocat/Hello-World/releases/download/v1.0.0/example.zip id : 1 node_id + * : MDEyOlJlbGVhc2VBc3NldDE= name : example.zip label : short description state : uploaded + * content_type : application/zip size : 1024 download_count : 42 created_at : + * 2013-02-27T19:35:32Z updated_at : 2013-02-27T19:35:32Z uploader : + * {"login":"octocat","id":1,"node_id":"MDQ6VXNlcjE=","avatar_url":"https://github.com/images/error/octocat_happy.gif","gravatar_id":"","url":"https://api.github.com/users/octocat","html_url":"https://github.com/octocat","followers_url":"https://api.github.com/users/octocat/followers","following_url":"https://api.github.com/users/octocat/following{/other_user}","gists_url":"https://api.github.com/users/octocat/gists{/gist_id}","starred_url":"https://api.github.com/users/octocat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/octocat/subscriptions","organizations_url":"https://api.github.com/users/octocat/orgs","repos_url":"https://api.github.com/users/octocat/repos","events_url":"https://api.github.com/users/octocat/events{/privacy}","received_events_url":"https://api.github.com/users/octocat/received_events","type":"User","site_admin":false} + */ + private String browser_download_url; + + private String name; + + private int size; + + public AssetsBean() { + } + + public String getBrowser_download_url() { + return browser_download_url; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/location/LocationOf.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/location/LocationOf.java new file mode 100644 index 0000000..f0d59ff --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/location/LocationOf.java @@ -0,0 +1,41 @@ +package org.abc.A.util.location; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.jetbrains.annotations.NotNull; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public final class LocationOf { + + @NotNull + private static final Pattern PATTERN = + Pattern.compile( + "((?[^:/]+)[:/])?(?[\\-0-9.]+),(?[\\-0-9.]+),(?[\\-0-9.]+)(:(?[\\-0-9.]+):(?[\\-0-9.]+))?"); + + @NotNull + private final String text; + + public LocationOf(@NotNull String text) { + this.text = text; + } + + @NotNull + public Location value() { + final Matcher match = PATTERN.matcher(text.replaceAll("_", "\\.")); + + if (match.matches()) { + return new Location( + Bukkit.getWorld(match.group("world")), + Double.parseDouble(match.group("x")), + Double.parseDouble(match.group("y")), + Double.parseDouble(match.group("z")), + match.group("yaw") != null ? Float.parseFloat(match.group("yaw")) : 0F, + match.group("pitch") != null ? Float.parseFloat(match.group("pitch")) : 0F); + } + + throw new IllegalStateException("Location string has wrong style!"); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/location/StringOf.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/location/StringOf.java new file mode 100644 index 0000000..e54f59f --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/location/StringOf.java @@ -0,0 +1,44 @@ +package org.abc.A.util.location; + +import java.util.Locale; +import org.bukkit.Location; +import org.bukkit.World; +import org.jetbrains.annotations.NotNull; + +public final class StringOf { + + @NotNull + private final Location location; + + @NotNull + private final World world; + + public StringOf(@NotNull Location location) { + if (location.getWorld() == null) { + throw new IllegalStateException("World of the location cannot be null!"); + } + + this.location = location; + this.world = location.getWorld(); + } + + @NotNull + public String asKey() { + return asString().replaceAll(":", "/").replaceAll("\\.", "_"); + } + + @NotNull + public String asString() { + String s = world.getName() + ":"; + + s += + String.format( + Locale.ENGLISH, "%.2f,%.2f,%.2f", location.getX(), location.getY(), location.getZ()); + + if (location.getYaw() != 0f || location.getPitch() != 0f) { + s += String.format(Locale.ENGLISH, ":%.2f:%.2f", location.getYaw(), location.getPitch()); + } + return s; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/logger/QuickShopLogger.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/logger/QuickShopLogger.java new file mode 100644 index 0000000..f8002cc --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/logger/QuickShopLogger.java @@ -0,0 +1,317 @@ +/* + * This file is a part of project QuickShop, the name is QuickShopLogger.java Copyright (C) + * Ghost_chu Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it under the terms of the + * GNU Lesser General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with this program. + * If not, see . + */ + +package org.abc.A.util.logger; + +import static org.bukkit.ChatColor.*; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import lombok.SneakyThrows; +import org.bukkit.ChatColor; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginLogger; + +/* + * Originally take from Mypet which is a awesome project, extends PluginLogger in order to replace + * the default logger. + * + * This is generally a new built logger system that rely on the Java logger to provide better + * customization. + */ +public class QuickShopLogger extends PluginLogger { + protected boolean debugSetup = false; + /** + * Mapping from the text pattern of Bukkit color to the corresponding text format of Ansi + */ + private Map bukkitToAnsi; + // below are non-static for secret optimization + /** + * Regex that indicates the case insensitive + */ + private String IGNORE_CASE; + // private FileHandler debugLogFileHandler = null; + private boolean hasAnsi; + + private boolean hasJline; + + @SneakyThrows + public QuickShopLogger(Plugin plugin) { + super(plugin); + registerStyles(); + + // Logger re-naming + String prefix = plugin.getDescription().getPrefix(); + String pluginName = (prefix != null ? "[" + ChatColor.YELLOW + prefix + ChatColor.RESET + "] " + : "[" + ChatColor.YELLOW + plugin.getDescription().getName() + ChatColor.RESET + "] "); + pluginName = applyStyles(pluginName); + + // Remove logger name from package name + Field nameField = Logger.class.getDeclaredField("name"); + nameField.setAccessible(true); // private + nameField.set(this, ""); + + // Apply plugin name for BukkitLogger + Field pluginNameField = PluginLogger.class.getDeclaredField("pluginName"); + pluginNameField.setAccessible(true); // private + pluginNameField.set(this, pluginName); + + // Ansi setup + try { + hasAnsi = org.fusesource.jansi.Ansi.isEnabled(); + } catch (NoClassDefFoundError e) { + hasAnsi = false; + info("Your server do not support Ansi, colour formatter will not be applied."); + } + + Class main = Class.forName("org.bukkit.craftbukkit.Main"); // Not in subversion + Field useJline = main.getField("useJline"); + hasJline = useJline.getBoolean(null); + if (!hasJline) { + info("As you have turned Jline off, colour formatter will not be applied."); + } + + this.config(); + // super.setUseParentHandlers(false); + } + + // Logging stuffs + @Override + public void log(LogRecord logRecord) { + String message = logRecord.getMessage(); + + if (message != null) { + + + if (logRecord.getLevel() == Level.WARNING) { + message = ChatColor.YELLOW + message; + } else if (logRecord.getLevel() == Level.SEVERE) { + message = ChatColor.RED + message; + } + + logRecord.setMessage(applyStyles(message)); + super.log(logRecord); + + } + } + + /** + * Apply Ansi styples to the specific message if it contains, internally converting Bukkit style + * color text to Ansi code or empty string if Ansi is not available. + * + * @param message to apply styles + * @return text maybe applied styles + */ + public String applyStyles(String message) { + for (Entry entry : bukkitToAnsi.entrySet()) { + message = + entry.getKey().matcher(message).replaceAll(hasAnsi && hasJline ? entry.getValue() : ""); + } + + return hasAnsi && hasJline ? message.concat(org.fusesource.jansi.Ansi.ansi().reset().toString()) + : message; + } + + public void info(Object... params) { + super.info(collectParams(params)); + } + + /** + * Collect params as a string with blank spaces between + * + * @param params Params + * @return collected string + */ + public String collectParams(Object... params) { + return Arrays.stream(params).map(String::valueOf).collect(Collectors.joining(" ")); + } + + public void warning(Object... params) { + + super.warning(collectParams(params)); + } + + public void severe(Object... params) { + + super.severe(collectParams(params)); + + } + + public void config(Object... params) { + + super.config(collectParams(params)); + + } + + public void fine(Object... params) { + + super.fine(collectParams(params)); + + } + + public void finer(Object... params) { + + super.finer(collectParams(params)); + + } + + public void finest(Object... params) { + + super.finest(collectParams(params)); + + } + + /* + * This will compile patterns for Bukkit colors as the key, and stringify Ansi as the value, then + * register in to the system. + */ + private void registerStyles() { + // Initial here for secert optimization + bukkitToAnsi = new HashMap<>(); + IGNORE_CASE = "(?i)"; + + // Colors + regAnsiMapping(BLACK, !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.BLACK); + regAnsiMapping(DARK_BLUE, !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.BLUE); + regAnsiMapping(DARK_GREEN, + !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.GREEN); + regAnsiMapping(DARK_AQUA, !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.CYAN); + regAnsiMapping(DARK_RED, !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.RED); + regAnsiMapping(DARK_PURPLE, + !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.MAGENTA); + regAnsiMapping(GOLD, !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.YELLOW); + regAnsiMapping(GRAY, !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.WHITE); + regAnsiMapping(DARK_GRAY, !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.BLACK, + true); + regAnsiMapping(BLUE, !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.BLUE, + true); + regAnsiMapping(GREEN, !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.GREEN, + true); + regAnsiMapping(AQUA, !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.CYAN, + true); + regAnsiMapping(RED, !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.RED, true); + regAnsiMapping(LIGHT_PURPLE, + !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.MAGENTA, true); + regAnsiMapping(YELLOW, !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.YELLOW, + true); + regAnsiMapping(WHITE, !(hasAnsi && hasJline) ? null : org.fusesource.jansi.Ansi.Color.WHITE, + true); + + // Effects + regAnsiMapping(MAGIC, org.fusesource.jansi.Ansi.Attribute.BLINK_SLOW); + regAnsiMapping(BOLD, org.fusesource.jansi.Ansi.Attribute.UNDERLINE_DOUBLE); + regAnsiMapping(STRIKETHROUGH, org.fusesource.jansi.Ansi.Attribute.STRIKETHROUGH_ON); + regAnsiMapping(UNDERLINE, org.fusesource.jansi.Ansi.Attribute.UNDERLINE); + regAnsiMapping(ITALIC, org.fusesource.jansi.Ansi.Attribute.ITALIC); + regAnsiMapping(RESET, org.fusesource.jansi.Ansi.Attribute.RESET); + } + + /* + * Register a mapping from Bukkit color to Ansi + */ + private void regAnsiMapping(ChatColor bukkColor, org.fusesource.jansi.Ansi.Color ansiColor) { + regAnsiMapping0(toPattern(bukkColor), toDesc(ansiColor)); + } + + /* + * Register a mapping from Bukkit color to Ansi + */ + private void regAnsiMapping(ChatColor bukkColor, + org.fusesource.jansi.Ansi.Attribute ansiAttribute) { + regAnsiMapping0(toPattern(bukkColor), toDesc(ansiAttribute)); + } + + /* + * Register a mapping from Bukkit color to Ansi, with color option + */ + private void regAnsiMapping(ChatColor bukkColor, org.fusesource.jansi.Ansi.Color ansiColor, + boolean intensity) { + regAnsiMapping0(toPattern(bukkColor), toDesc(ansiColor, intensity)); + } + + /* + * Register a mapping from the pattern of Bukkit color to the description of Ansi, and this is the + * genuine type for them to be registered. + */ + private void regAnsiMapping0(Pattern bukkitPattern, String ansiDesc) { + this.bukkitToAnsi.put(bukkitPattern, ansiDesc); + } + + /** + * Convert a Bukkit color to regex pattern + * + * @param bukkitColor the bukkit color + * @return the pattern + */ + private Pattern toPattern(ChatColor bukkitColor) { + return Pattern.compile(IGNORE_CASE.concat(bukkitColor.toString())); + } + + /** + * To populate a Ansi with a reset attribute ahead + * + * @param ansiColor the Ansi need to add reset attribute + * @return Ansi with reset ahead + */ + private org.fusesource.jansi.Ansi resetWith(org.fusesource.jansi.Ansi.Color ansiColor) { + return org.fusesource.jansi.Ansi.ansi().a(org.fusesource.jansi.Ansi.Attribute.RESET) + .fg(ansiColor); + } + + /** + * Convert a Ansi to its description text + * + * @param ansiColor Ansi + * @param intensity Ansi color option + * @return stringified Ansi + */ + private String toDesc(org.fusesource.jansi.Ansi.Color ansiColor, boolean intensity) { + return hasAnsi && hasJline + ? (intensity ? resetWith(ansiColor).bold().toString() : toDesc(ansiColor)) + : ""; + } + + /** + * Convert a Ansi to its description text + * + * @param ansiColor Ansi + * @return stringified Ansi + */ + private String toDesc(org.fusesource.jansi.Ansi.Color ansiColor) { + return hasAnsi && hasJline ? resetWith(ansiColor).boldOff().toString() : ""; + } + + /** + * Convert a Ansi to its description text + * + * @param ansiAttribute Ansi + * @return stringified Ansi + */ + private String toDesc(org.fusesource.jansi.Ansi.Attribute ansiAttribute) { + return hasAnsi && hasJline + ? org.fusesource.jansi.Ansi.ansi().a(org.fusesource.jansi.Ansi.Attribute.RESET).toString() + : ""; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/matcher/item/BukkitItemMatcherImpl.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/matcher/item/BukkitItemMatcherImpl.java new file mode 100644 index 0000000..d314d22 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/matcher/item/BukkitItemMatcherImpl.java @@ -0,0 +1,51 @@ +package org.abc.A.util.matcher.item; + +import lombok.AllArgsConstructor; +import org.abc.A.QuickShop; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@AllArgsConstructor +public class BukkitItemMatcherImpl implements ItemMatcher { + private QuickShop plugin; + /** + * Gets the ItemMatcher provider name + * + * @return Provider name + */ + @Override + public @NotNull String getName() { + return plugin.getName(); + } + + /** + * Gets the ItemMatcher provider plugin instance + * + * @return Provider Plugin instance + */ + @Override + public @NotNull Plugin getPlugin() { + return plugin; + } + + /** + * Tests ItemStacks is matches + * ->BEWARE: Different order of itemstacks you might will got different results<- + * + * @param original The original ItemStack + * @param tester The ItemStack will test matches with original itemstack. + * @return The result of tests + */ + @Override + public boolean matches(@Nullable ItemStack original, @Nullable ItemStack tester) { + if(original == null && tester == null){ + return true; + } + if((original == null) != (tester == null)){ + return false; + } + return tester.isSimilar(original); + } +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/matcher/item/ItemMatcher.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/matcher/item/ItemMatcher.java new file mode 100644 index 0000000..e8c7881 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/matcher/item/ItemMatcher.java @@ -0,0 +1,28 @@ +package org.abc.A.util.matcher.item; + +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +public interface ItemMatcher { + /** + * Gets the ItemMatcher provider name + * @return Provider name + */ + @NotNull String getName(); + + /** + * Gets the ItemMatcher provider plugin instance + * @return Provider Plugin instance + */ + @NotNull Plugin getPlugin(); + + /** + * Tests ItemStacks is matches + * ->BEWARE: Different order of itemstacks you might will got different results<- + * @param original The original ItemStack + * @param tester The ItemStack will test matches with original itemstack. + * @return The result of tests + */ + boolean matches(@NotNull ItemStack original, @NotNull ItemStack tester); +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/matcher/item/QuickShopItemMatcherImpl.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/matcher/item/QuickShopItemMatcherImpl.java new file mode 100644 index 0000000..fed38ee --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/matcher/item/QuickShopItemMatcherImpl.java @@ -0,0 +1,549 @@ +package org.abc.A.util.matcher.item; + +import lombok.AllArgsConstructor; +import org.abc.A.QuickShop; +import org.abc.A.util.Util; +import org.bukkit.attribute.Attribute; +import org.bukkit.block.ShulkerBox; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.*; +import org.bukkit.plugin.Plugin; +import org.bukkit.potion.PotionData; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +@AllArgsConstructor +public class QuickShopItemMatcherImpl implements ItemMatcher { + private QuickShop plugin; + + private ItemMetaMatcher itemMetaMatcher; + public QuickShopItemMatcherImpl(@NotNull QuickShop plugin) { + this.plugin = plugin; + itemMetaMatcher=new ItemMetaMatcher(plugin.getConfig().getConfigurationSection("matcher.item"),this); + } + + public QuickShopItemMatcherImpl() { + this.plugin = QuickShop.getInstance(); + itemMetaMatcher=new ItemMetaMatcher(plugin.getConfig().getConfigurationSection("matcher.item"),this); + } + + /** + * Gets the ItemMatcher provider name + * + * @return Provider name + */ + @Override + public @NotNull String getName() { + return plugin.getName(); + } + + /** + * Gets the ItemMatcher provider plugin instance + * + * @return Provider Plugin instance + */ + @Override + public @NotNull Plugin getPlugin() { + return plugin; + } + + /** + * Tests ItemStacks is matches + * ->BEWARE: Different order of itemstacks you might will got different results<- + * + * @param requireStack The original ItemStack + * @param givenStack The ItemStack will test matches with original itemstack. + * @return The result of tests + */ + public boolean matches(@Nullable ItemStack[] requireStack, @Nullable ItemStack[] givenStack) { + if (requireStack == null && givenStack == null) { + return true; + } + + if (requireStack == null || givenStack == null) { + return false; + } + + if (requireStack.length != givenStack.length) { + return false; + } + //For performance, we just check really equals in each index,check isn't contain or match will cost n^n time in most + for (int i = 0; i < requireStack.length; i++) { + //IDEA bug, ignore NPE tips + //noinspection ConstantConditions + if ((requireStack[i] != null) && (givenStack[i] != null) && + (requireStack[i].getAmount() != givenStack[i].getAmount())) { + return false; + } + + if (!matches(requireStack[i], givenStack[i])) { + return false; + } + } + return true; + } + + /** + * Compares two items to each other. Returns true if they match. Rewrite it to use more faster + * hashCode. + * + * @param requireStack The first item stack + * @param givenStack The second item stack + * @return true if the itemstacks match. (Material, durability, enchants, name) + */ + public boolean matches(@Nullable ItemStack requireStack, @Nullable ItemStack givenStack) { + if (requireStack == null && givenStack == null) { + return true; + } + + if (requireStack == null || givenStack == null) { + Util.debugLog( + "Match failed: A stack is null: " + + "requireStack[" + + requireStack + + "] givenStack[" + + givenStack + + "]"); + return false; // One of them is null (Can't be both, see above) + } + + requireStack = requireStack.clone(); + requireStack.setAmount(1); + givenStack = givenStack.clone(); + givenStack.setAmount(1); + switch (plugin.getConfig().getInt("matcher.work-type")) { + case 1: + return requireStack.isSimilar(givenStack); + case 2: + return requireStack.equals(givenStack); + } + + if (!typeMatches(requireStack, givenStack)) { + return false; + } + + // if (requireStack.hasItemMeta() != givenStack.hasItemMeta()) { + // Util.debugLog("Meta not matched"); + // return false; + + if (requireStack.hasItemMeta()) { + if (!givenStack.hasItemMeta()) { + return false; + } + return itemMetaMatcher.matches(requireStack, givenStack); + } + + return true; + } + + private boolean typeMatches(ItemStack requireStack, ItemStack givenStack) { + return requireStack.getType().equals(givenStack.getType()); + } + + private static class ItemMetaMatcher { + + interface Matcher { + + boolean match(ItemMeta meta1, ItemMeta meta2); + + } + + private final List matcherList = new LinkedList<>(); + + + private void addIfEnable(ConfigurationSection itemMatcherConfig, String path, Matcher matcher) { + if (itemMatcherConfig.getBoolean(path)) { + matcherList.add(matcher); + } + } + + public ItemMetaMatcher(@NotNull ConfigurationSection itemMatcherConfig, @NotNull QuickShopItemMatcherImpl itemMatcher) { + + addIfEnable(itemMatcherConfig, "damage", (meta1, meta2) -> { + // if (!(meta1 instanceof Damageable)) { + // return true; //No damage need to check. + // } + // if(!(meta2 instanceof Damageable)){ + // return false; + // } + try { + Damageable damage1 = (Damageable) meta1; + Damageable damage2 = (Damageable) meta2; + // Check them damages, if givenDamage >= requireDamage, allow it. + return damage2.getDamage() <= damage1.getDamage(); + } catch (Throwable th) { + th.printStackTrace(); + return true; + } + }); + addIfEnable(itemMatcherConfig, "repaircost", (meta1, meta2) -> { + if (!(meta1 instanceof Repairable)) { + return true; + } + if (!(meta2 instanceof Repairable)) { + return false; + } + Repairable repairable1 = (Repairable) meta1; + Repairable repairable2 = (Repairable) meta2; + if (repairable1.hasRepairCost() != repairable2.hasRepairCost()) { + return false; + } + if (repairable1.hasRepairCost()) { + return repairable2.getRepairCost() <= repairable1.getRepairCost(); + } + return true; + }); + addIfEnable(itemMatcherConfig, "displayname", ((meta1, meta2) -> { + if (!meta1.hasDisplayName()) { + return true; + } else { + if (!meta2.hasDisplayName()) { + return false; + } + return meta1.getDisplayName().equals(meta2.getDisplayName()); + } + })); + // We didn't touch the loresMatches because many plugin use this check item. + addIfEnable(itemMatcherConfig, "lores", ((meta1, meta2) -> { + if (meta1.hasLore() != meta2.hasLore()) { + return false; + } + if (!meta1.hasLore()) { + return true; // No lores need to be checked. + } + List lores1 = meta1.getLore(); + List lores2 = meta2.getLore(); + return Arrays.deepEquals( + Objects.requireNonNull(lores1).toArray(), Objects.requireNonNull(lores2).toArray()); + + })); + addIfEnable(itemMatcherConfig, "enchs", ((meta1, meta2) -> { + if (meta1.hasEnchants()) { + if (!meta2.hasEnchants()) { + return false; + } + Map enchMap1 = meta1.getEnchants(); + Map enchMap2 = meta2.getEnchants(); + if (!Util.mapMatches(enchMap1, enchMap2)) { + return false; + } + } + if ((meta1 instanceof EnchantmentStorageMeta)) { + if (!(meta2 instanceof EnchantmentStorageMeta)) { + return false; + } + Map stor1 = ((EnchantmentStorageMeta) meta1).getStoredEnchants(); + Map stor2 = ((EnchantmentStorageMeta) meta2).getStoredEnchants(); + return Util.mapMatches(stor1, stor2); + } + return true; + })); + addIfEnable(itemMatcherConfig, "potions", ((meta1, meta2) -> { + if ((meta1 instanceof PotionMeta) != (meta2 instanceof PotionMeta)) { + return false; + } + + if (!(meta1 instanceof PotionMeta)) { + return true; // No potion meta needs to be checked. + } + + PotionMeta potion1 = (PotionMeta) meta1; + PotionMeta potion2 = (PotionMeta) meta2; + + if (potion1.hasColor()) { + if (!potion2.hasColor()) { + return false; + } else { + if (!Objects.requireNonNull(potion1.getColor()).equals(potion2.getColor())) { + return false; + } + } + } + if (potion1.hasCustomEffects()) { + if (!potion2.hasCustomEffects()) { + return false; + } + if (!Arrays.deepEquals( + potion1.getCustomEffects().toArray(), potion2.getCustomEffects().toArray())) { + return false; + } + // if + // (!Util.listMatches(potion1.getCustomEffects(),potion2.getCustomEffects())) { + // return false; + // } + } + PotionData data1 = potion1.getBasePotionData(); + PotionData data2 = potion2.getBasePotionData(); + if (data2.equals(data1)) { + return true; + } + if (!data2.getType().equals(data1.getType())) { + return false; + } + if (data1.isExtended()) { + if (!data2.isExtended()) { + return false; + } + } + if (data1.isUpgraded()) { + //noinspection RedundantIfStatement + if (!data2.isUpgraded()) { + return false; + } + } + return true; + })); + addIfEnable(itemMatcherConfig, "attributes", (meta1, meta2) -> { // requireStack doen't need require must have AM, skipping.. + if (!meta1.hasAttributeModifiers()) { + return true; + } else { + // If require AM but hadn't, the item not matched. + if (!meta2.hasAttributeModifiers()) { + return false; + } + Set set1 = Objects.requireNonNull(meta1.getAttributeModifiers()).keySet(); + Set set2 = Objects.requireNonNull(meta2.getAttributeModifiers()).keySet(); + for (Attribute att : set1) { + if (!set2.contains(att)) { + return false; + } else if (!meta1 + .getAttributeModifiers() + .get(att) + .equals(meta2.getAttributeModifiers().get(att))) { + return false; + } + } + return true; + } + }); + addIfEnable(itemMatcherConfig, "itemflags", ((meta1, meta2) -> { + if (meta1.getItemFlags().isEmpty()) { + return true; + } else { + if (meta2.getItemFlags().isEmpty()) { + return false; + } + return Arrays.deepEquals(meta1.getItemFlags().toArray(), meta2.getItemFlags().toArray()); + } + })); + addIfEnable(itemMatcherConfig, "custommodeldata", ((meta1, meta2) -> { + try { + if (!meta1.hasCustomModelData()) { + return true; + } else { + if (!meta2.hasCustomModelData()) { + return false; + } + return meta1.getCustomModelData() == meta2.getCustomModelData(); + } + } catch (NoSuchMethodError err) { + // Ignore, for 1.13 compatibility + return true; + } + })); + addIfEnable(itemMatcherConfig, "book", ((meta1, meta2) -> { + if (!(meta1 instanceof BookMeta)) { + return true; + } + if (!(meta2 instanceof BookMeta)) { + return false; + } + BookMeta book1 = (BookMeta) meta1; + BookMeta book2 = (BookMeta) meta2; + if (book1.hasTitle()) { + if (!book2.hasTitle()) { + return false; + } + if (!Objects.equals(book1.getTitle(), book2.getTitle())) { + return false; + } + } + if (book1.hasPages()) { + if (!book2.hasPages()) { + return false; + } + if (!book1.getPages().equals(book2.getPages())) { + return false; + } + } + if (book1.hasAuthor()) { + if (!book2.hasAuthor()) { + return false; + } + if (!Objects.equals(book1.getAuthor(), book2.getAuthor())) { + return false; + } + } + if (book1.hasGeneration()) { + if (!book2.hasGeneration()) { + return false; + } + return Objects.equals(book1.getGeneration(), book2.getGeneration()); + } + return true; + })); + addIfEnable(itemMatcherConfig, "banner", ((meta1, meta2) -> { + if ((meta1 instanceof BannerMeta) != (meta2 instanceof BannerMeta)) { + return false; + } + if (!(meta1 instanceof BannerMeta)) { + return true; + } + BannerMeta bannerMeta1 = (BannerMeta) meta1; + BannerMeta bannerMeta2 = (BannerMeta) meta2; + if (bannerMeta1.numberOfPatterns() != bannerMeta2.numberOfPatterns()) { + return false; + } + return Util.listMatches(bannerMeta1.getPatterns(), bannerMeta2.getPatterns()); + })); + addIfEnable(itemMatcherConfig, "skull", (meta1, meta2) -> { + if ((meta1 instanceof SkullMeta) != (meta2 instanceof SkullMeta)) { + return false; + } + if (!(meta1 instanceof SkullMeta)) { + return true; + } + //getOwningPlayer will let server query playerProfile in server thread + //Causing huge lag, so using String instead + String player1 = ((SkullMeta) meta1).getOwner(); + String player2 = ((SkullMeta) meta2).getOwner(); + if (player1 == null) { + return true; + } + return player1.equalsIgnoreCase(player2); + }); + addIfEnable(itemMatcherConfig, "map", (meta1, meta2) -> { + if ((meta1 instanceof MapMeta) != (meta2 instanceof MapMeta)) { + return false; + } + if (!(meta1 instanceof MapMeta)) { + return true; + } + MapMeta mapMeta1 = ((MapMeta) meta1); + MapMeta mapMeta2 = ((MapMeta) meta2); + if (!mapMeta1.hasMapView() || mapMeta1.getMapView() == null) { + return true; + } + if (!mapMeta1.getMapView().equals(mapMeta2.getMapView())) { + return false; + } + + if (!mapMeta1.hasColor() || mapMeta1.getColor() == null) { + return true; + } + if (!mapMeta1.getColor().equals(mapMeta2.getColor())) { + return false; + } + + if (!mapMeta1.hasLocationName() || mapMeta1.getLocationName() == null) { + return true; + } + return mapMeta1.getLocationName().equals(mapMeta2.getLocationName()); + }); + addIfEnable(itemMatcherConfig, "firework", (meta1, meta2) -> { + if ((meta1 instanceof FireworkMeta) != (meta2 instanceof FireworkMeta)) { + return false; + } + if (!(meta1 instanceof FireworkMeta)) { + return true; + } + FireworkMeta fireworkMeta1 = ((FireworkMeta) meta1); + FireworkMeta fireworkMeta2 = ((FireworkMeta) meta2); + if (!fireworkMeta1.hasEffects()) { + return true; + } + if (!fireworkMeta1.getEffects().equals(fireworkMeta2.getEffects())) { + return false; + } + return fireworkMeta1.getPower() == fireworkMeta2.getPower(); + }); + addIfEnable(itemMatcherConfig, "leatherArmor", ((meta1, meta2) -> { + if ((meta1 instanceof LeatherArmorMeta) != (meta2 instanceof LeatherArmorMeta)) { + return false; + } + if (!(meta1 instanceof LeatherArmorMeta)) { + return true; + } + return ((LeatherArmorMeta) meta1).getColor().equals(((LeatherArmorMeta) meta2).getColor()); + })); + addIfEnable(itemMatcherConfig, "fishBucket", (meta1, meta2) -> { + if ((meta1 instanceof TropicalFishBucketMeta) != (meta2 instanceof TropicalFishBucketMeta)) { + return false; + } + if (!(meta1 instanceof TropicalFishBucketMeta)) { + return true; + } + TropicalFishBucketMeta fishBucketMeta1 = ((TropicalFishBucketMeta) meta1); + TropicalFishBucketMeta fishBucketMeta2 = ((TropicalFishBucketMeta) meta2); + if (!fishBucketMeta1.hasVariant()) { + return true; + } + + return fishBucketMeta2.hasVariant() && fishBucketMeta1.getPattern() == fishBucketMeta2.getPattern() + && fishBucketMeta1.getBodyColor().equals(fishBucketMeta2.getBodyColor()) + && fishBucketMeta1.getPatternColor().equals(fishBucketMeta2.getPatternColor()); + }); + addIfEnable(itemMatcherConfig, "suspiciousStew", ((meta1, meta2) -> { + if ((meta1 instanceof SuspiciousStewMeta) != (meta2 instanceof SuspiciousStewMeta)) { + return false; + } + if (!(meta1 instanceof SuspiciousStewMeta)) { + return true; + } + SuspiciousStewMeta stewMeta1 = ((SuspiciousStewMeta) meta1); + SuspiciousStewMeta stewMeta2 = ((SuspiciousStewMeta) meta2); + if (!stewMeta1.hasCustomEffects()) { + return true; + } + return stewMeta1.getCustomEffects().equals(stewMeta2.getCustomEffects()); + })); + addIfEnable(itemMatcherConfig, "shulkerBox", ((meta1, meta2) -> { + //https://www.spigotmc.org/threads/getting-the-inventory-of-a-shulker-box-itemstack.212369 + if ((meta1 instanceof BlockStateMeta) != (meta2 instanceof BlockStateMeta)) { + return false; + } + if (!(meta1 instanceof BlockStateMeta)) { + return true; + } + + if ((((BlockStateMeta) meta1).getBlockState() instanceof ShulkerBox) != ((BlockStateMeta) meta2).getBlockState() instanceof ShulkerBox) { + return false; + } + if (!(((BlockStateMeta) meta1).getBlockState() instanceof ShulkerBox)) { + return true; + } + return itemMatcher.matches(((ShulkerBox) ((BlockStateMeta) meta1).getBlockState()).getInventory().getContents(), ((ShulkerBox) ((BlockStateMeta) meta2).getBlockState()).getInventory().getContents()); + })); + + } + + + boolean matches(ItemStack requireStack, ItemStack givenStack) { + if (requireStack.hasItemMeta() != givenStack.hasItemMeta()) { + return false; + } + if (!requireStack.hasItemMeta()) { + return true; // Passed check. no meta need to check. + } + ItemMeta meta1 = requireStack.getItemMeta(); + ItemMeta meta2 = givenStack.getItemMeta(); + for (Matcher matcher : matcherList) { + if (!matcher.match(meta1, meta2)) { + return false; + } + } + return true; + } + + + private boolean rootMatches(ItemMeta meta1, ItemMeta meta2) { + return (meta1.hashCode() == meta2.hashCode()); + } + + + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/AssetJson.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/AssetJson.java new file mode 100644 index 0000000..bada511 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/AssetJson.java @@ -0,0 +1,73 @@ +/* + * This file is a part of project QuickShop, the name is AssetJson.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util.mojangapi; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; +import org.abc.A.util.MsgUtil; +import org.abc.A.util.Util; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class AssetJson { + final String pathTemplate = "minecraft/lang/{0}.json"; + + @NotNull + final String gameAssets; + + public AssetJson(@NotNull String json) { + this.gameAssets = json; + } + + @Nullable + public String getLanguageHash(@NotNull String languageCode) { + languageCode = languageCode.replace("-", "_").toLowerCase().trim(); + JsonObject json = new JsonParser().parse(this.gameAssets).getAsJsonObject(); + if (json == null || json.isJsonNull()) { + Util.debugLog("Cannot parse the json: " + this.gameAssets); + return null; + } + JsonElement obje = json.get("objects"); + if (obje == null) { + Util.debugLog("Json element is null for json " + this.gameAssets); + return null; + } + JsonObject objs = obje.getAsJsonObject(); + if (objs == null || objs.isJsonNull()) { + Util.debugLog("Json object is null."); + return null; + } + JsonObject langObj = objs.getAsJsonObject(MsgUtil.fillArgs(pathTemplate, languageCode)); + if (langObj == null || langObj.isJsonNull()) { + Util.debugLog("Cannot find request path."); + Util.debugLog(this.gameAssets); + return null; + } + JsonPrimitive hashObj = langObj.getAsJsonPrimitive("hash"); + if (hashObj == null || hashObj.isJsonNull()) { + Util.debugLog("Cannot get hash."); + return null; + } + return hashObj.getAsString(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/MojangAPI.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/MojangAPI.java new file mode 100644 index 0000000..079f1e6 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/MojangAPI.java @@ -0,0 +1,126 @@ +/* + * This file is a part of project QuickShop, the name is MojangAPI.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util.mojangapi; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; +import java.io.File; +import java.io.IOException; +import java.net.URL; + +import org.abc.A.QuickShop; +import org.abc.A.L.com.sk89q.worldedit.util.net.HttpRequest; +import org.abc.A.util.Util; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class MojangAPI { + final String versionManifestUrl = "https://launchermeta.mojang.com/mc/game/version_manifest.json"; + + final String assetsUrl = "https://resources.download.minecraft.net/"; + + final String pathTemplate = "minecraft/lang/{0}.json"; + + final Gson gson = new Gson(); + + @Nullable + public String getAssetIndexJson(@NotNull String mcVer) throws IOException { + String versionJson = getVersionJson(mcVer); + if (versionJson == null) { + return null; + } + JsonObject rootObj = new JsonParser().parse(versionJson).getAsJsonObject(); + JsonObject assetIndex = rootObj.getAsJsonObject("assetIndex"); + if (assetIndex == null) { + Util.debugLog("Cannot get assetIndex obj."); + return null; + } + JsonPrimitive urlObj = assetIndex.getAsJsonPrimitive("url"); + if (urlObj == null) { + Util.debugLog("Cannot get asset url obj."); + return null; + } + String url = urlObj.getAsString(); + if (url == null) { + Util.debugLog("Cannot get asset url."); + return null; + } + return HttpRequest.get(new URL(url)) + .execute() + .expectResponseCode(200) + .returnContent() + .asString("UTF-8") + .trim(); + } + + @Nullable + public String getVersionJson(@NotNull String mcVer) throws IOException { + VersionList list = gson.fromJson(this.getVersionManifest(), VersionList.class); + for (VersionList.VersionsBean mcv : list.getVersions()) { + if (mcv.getId().equals(mcVer)) { + try { + QuickShop.instance.getLogger().info("Downloading version index..."); + return HttpRequest.get(new URL(mcv.getUrl())) + .execute() + .expectResponseCode(200) + .returnContent() + .asString("UTF-8") + .trim(); + } catch (IOException e) { + Util.debugLog(e.getMessage()); + return null; + } + } + } + return null; + } + + @Nullable + public String getVersionManifest() throws IOException { + QuickShop.instance.getLogger().info("Downloading version manifest..."); + return HttpRequest.get(new URL(versionManifestUrl)) + .execute() + .expectResponseCode(200) + .returnContent() + .asString("UTF-8") + .trim(); + } + + @Nullable + public String downloadTextFileFromMojang(@NotNull String hash) throws IOException { + File cacheFile = new File(Util.getCacheFolder(), hash); + if (cacheFile.exists()) { + return Util.readToString(cacheFile); + } + String data; + QuickShop.instance.getLogger().info("Downloading assets file..."); + data = + HttpRequest.get(new URL(this.assetsUrl + hash.substring(0, 2) + "/" + hash)) + .execute() + .expectResponseCode(200) + .returnContent() + .asString("UTF-8") + .trim(); + return data; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/PerVersionJson.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/PerVersionJson.java new file mode 100644 index 0000000..fcb73d9 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/PerVersionJson.java @@ -0,0 +1,805 @@ +/* + * This file is a part of project QuickShop, the name is PerVersionJson.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util.mojangapi; + +import java.util.List; + +public class PerVersionJson { + + /** + * arguments : + * {"game":["--username","${auth_player_name}","--version","${version_name}","--gameDir","${game_directory}","--assetsDir","${assets_root}","--assetIndex","${assets_index_name}","--uuid","${auth_uuid}","--accessToken","${auth_access_token}","--userType","${user_type}","--versionType","${version_type}",{"rules":[{"action":"allow","features":{"is_demo_user":true}}],"value":"--demo"},{"rules":[{"action":"allow","features":{"has_custom_resolution":true}}],"value":["--width","${resolution_width}","--height","${resolution_height}"]}],"jvm":[{"rules":[{"action":"allow","os":{"name":"osx"}}],"value":["-XstartOnFirstThread"]},{"rules":[{"action":"allow","os":{"name":"windows"}}],"value":"-XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump"},{"rules":[{"action":"allow","os":{"name":"windows","version":"^10\\."}}],"value":["-Dos.name=Windows + * 10","-Dos.version=10.0"]},{"rules":[{"action":"allow","os":{"arch":"x86"}}],"value":"-Xss1M"},"-Djava.library.path=${natives_directory}","-Dminecraft.launcher.brand=${launcher_name}","-Dminecraft.launcher.version=${launcher_version}","-cp","${classpath}"]} + * assetIndex : + * {"id":"1.15","sha1":"62745391056f1d0e1ffc808a0d4f0145b668ca24","size":234874,"totalSize":216306372,"url":"https://launchermeta.mojang.com/v1/packages/62745391056f1d0e1ffc808a0d4f0145b668ca24/1.15.json"} + * assets : 1.15 downloads : + * {"client":{"sha1":"8b11614bea9293592a947ea8f4fd72981ea66677","size":15518397,"url":"https://launcher.mojang.com/v1/objects/8b11614bea9293592a947ea8f4fd72981ea66677/client.jar"},"client_mappings":{"sha1":"cc77cb804c2cc0fa151b0745df4c5de8e64d1bb5","size":4962913,"url":"https://launcher.mojang.com/v1/objects/cc77cb804c2cc0fa151b0745df4c5de8e64d1bb5/client.txt"},"server":{"sha1":"4d1826eebac84847c71a77f9349cc22afd0cf0a1","size":36164938,"url":"https://launcher.mojang.com/v1/objects/4d1826eebac84847c71a77f9349cc22afd0cf0a1/server.jar"},"server_mappings":{"sha1":"47f8a03f5492223753f5f2b531d4938813903684","size":3730004,"url":"https://launcher.mojang.com/v1/objects/47f8a03f5492223753f5f2b531d4938813903684/server.txt"}} + * id : 1.15.1 libraries : + * [{"downloads":{"artifact":{"path":"com/mojang/patchy/1.1/patchy-1.1.jar","sha1":"aef610b34a1be37fa851825f12372b78424d8903","size":15817,"url":"https://libraries.minecraft.net/com/mojang/patchy/1.1/patchy-1.1.jar"}},"name":"com.mojang:patchy:1.1"},{"downloads":{"artifact":{"path":"oshi-project/oshi-core/1.1/oshi-core-1.1.jar","sha1":"9ddf7b048a8d701be231c0f4f95fd986198fd2d8","size":30973,"url":"https://libraries.minecraft.net/oshi-project/oshi-core/1.1/oshi-core-1.1.jar"}},"name":"oshi-project:oshi-core:1.1"},{"downloads":{"artifact":{"path":"net/java/dev/jna/jna/4.4.0/jna-4.4.0.jar","sha1":"cb208278274bf12ebdb56c61bd7407e6f774d65a","size":1091208,"url":"https://libraries.minecraft.net/net/java/dev/jna/jna/4.4.0/jna-4.4.0.jar"}},"name":"net.java.dev.jna:jna:4.4.0"},{"downloads":{"artifact":{"path":"net/java/dev/jna/platform/3.4.0/platform-3.4.0.jar","sha1":"e3f70017be8100d3d6923f50b3d2ee17714e9c13","size":913436,"url":"https://libraries.minecraft.net/net/java/dev/jna/platform/3.4.0/platform-3.4.0.jar"}},"name":"net.java.dev.jna:platform:3.4.0"},{"downloads":{"artifact":{"path":"com/ibm/icu/icu4j-core-mojang/51.2/icu4j-core-mojang-51.2.jar","sha1":"63d216a9311cca6be337c1e458e587f99d382b84","size":1634692,"url":"https://libraries.minecraft.net/com/ibm/icu/icu4j-core-mojang/51.2/icu4j-core-mojang-51.2.jar"}},"name":"com.ibm.icu:icu4j-core-mojang:51.2"},{"downloads":{"artifact":{"path":"com/mojang/javabridge/1.0.22/javabridge-1.0.22.jar","sha1":"6aa6453aa99a52a5cd91749da1af6ab70e082ab3","size":5111,"url":"https://libraries.minecraft.net/com/mojang/javabridge/1.0.22/javabridge-1.0.22.jar"}},"name":"com.mojang:javabridge:1.0.22"},{"downloads":{"artifact":{"path":"net/sf/jopt-simple/jopt-simple/5.0.3/jopt-simple-5.0.3.jar","sha1":"cdd846cfc4e0f7eefafc02c0f5dce32b9303aa2a","size":78175,"url":"https://libraries.minecraft.net/net/sf/jopt-simple/jopt-simple/5.0.3/jopt-simple-5.0.3.jar"}},"name":"net.sf.jopt-simple:jopt-simple:5.0.3"},{"downloads":{"artifact":{"path":"io/netty/netty-all/4.1.25.Final/netty-all-4.1.25.Final.jar","sha1":"d0626cd3108294d1d58c05859add27b4ef21f83b","size":3823147,"url":"https://libraries.minecraft.net/io/netty/netty-all/4.1.25.Final/netty-all-4.1.25.Final.jar"}},"name":"io.netty:netty-all:4.1.25.Final"},{"downloads":{"artifact":{"path":"com/google/guava/guava/21.0/guava-21.0.jar","sha1":"3a3d111be1be1b745edfa7d91678a12d7ed38709","size":2521113,"url":"https://libraries.minecraft.net/com/google/guava/guava/21.0/guava-21.0.jar"}},"name":"com.google.guava:guava:21.0"},{"downloads":{"artifact":{"path":"org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar","sha1":"6c6c702c89bfff3cd9e80b04d668c5e190d588c6","size":479881,"url":"https://libraries.minecraft.net/org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar"}},"name":"org.apache.commons:commons-lang3:3.5"},{"downloads":{"artifact":{"path":"commons-io/commons-io/2.5/commons-io-2.5.jar","sha1":"2852e6e05fbb95076fc091f6d1780f1f8fe35e0f","size":208700,"url":"https://libraries.minecraft.net/commons-io/commons-io/2.5/commons-io-2.5.jar"}},"name":"commons-io:commons-io:2.5"},{"downloads":{"artifact":{"path":"commons-codec/commons-codec/1.10/commons-codec-1.10.jar","sha1":"4b95f4897fa13f2cd904aee711aeafc0c5295cd8","size":284184,"url":"https://libraries.minecraft.net/commons-codec/commons-codec/1.10/commons-codec-1.10.jar"}},"name":"commons-codec:commons-codec:1.10"},{"downloads":{"artifact":{"path":"net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar","sha1":"39c7796b469a600f72380316f6b1f11db6c2c7c4","size":208338,"url":"https://libraries.minecraft.net/net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar"}},"name":"net.java.jinput:jinput:2.0.5"},{"downloads":{"artifact":{"path":"net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar","sha1":"e12fe1fda814bd348c1579329c86943d2cd3c6a6","size":7508,"url":"https://libraries.minecraft.net/net/java/jutils/jutils/1.0.0/jutils-1.0.0.jar"}},"name":"net.java.jutils:jutils:1.0.0"},{"downloads":{"artifact":{"path":"com/mojang/brigadier/1.0.17/brigadier-1.0.17.jar","sha1":"c6b7dc51dd44379cc751b7504816006e9be4b1e6","size":77392,"url":"https://libraries.minecraft.net/com/mojang/brigadier/1.0.17/brigadier-1.0.17.jar"}},"name":"com.mojang:brigadier:1.0.17"},{"downloads":{"artifact":{"path":"com/mojang/datafixerupper/2.0.24/datafixerupper-2.0.24.jar","sha1":"0944c24a8519981847ffb36c6dcd059d96fcb4b0","size":436066,"url":"https://libraries.minecraft.net/com/mojang/datafixerupper/2.0.24/datafixerupper-2.0.24.jar"}},"name":"com.mojang:datafixerupper:2.0.24"},{"downloads":{"artifact":{"path":"com/google/code/gson/gson/2.8.0/gson-2.8.0.jar","sha1":"c4ba5371a29ac9b2ad6129b1d39ea38750043eff","size":231952,"url":"https://libraries.minecraft.net/com/google/code/gson/gson/2.8.0/gson-2.8.0.jar"}},"name":"com.google.code.gson:gson:2.8.0"},{"downloads":{"artifact":{"path":"com/mojang/authlib/1.5.25/authlib-1.5.25.jar","sha1":"9834cdf236c22e84b946bba989e2f94ef5897c3c","size":65621,"url":"https://libraries.minecraft.net/com/mojang/authlib/1.5.25/authlib-1.5.25.jar"}},"name":"com.mojang:authlib:1.5.25"},{"downloads":{"artifact":{"path":"org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.jar","sha1":"a698750c16740fd5b3871425f4cb3bbaa87f529d","size":365552,"url":"https://libraries.minecraft.net/org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.jar"}},"name":"org.apache.commons:commons-compress:1.8.1"},{"downloads":{"artifact":{"path":"org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar","sha1":"18f4247ff4572a074444572cee34647c43e7c9c7","size":589512,"url":"https://libraries.minecraft.net/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar"}},"name":"org.apache.httpcomponents:httpclient:4.3.3"},{"downloads":{"artifact":{"path":"commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar","sha1":"f6f66e966c70a83ffbdb6f17a0919eaf7c8aca7f","size":62050,"url":"https://libraries.minecraft.net/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar"}},"name":"commons-logging:commons-logging:1.1.3"},{"downloads":{"artifact":{"path":"org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar","sha1":"31fbbff1ddbf98f3aa7377c94d33b0447c646b6e","size":282269,"url":"https://libraries.minecraft.net/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar"}},"name":"org.apache.httpcomponents:httpcore:4.3.2"},{"downloads":{"artifact":{"path":"it/unimi/dsi/fastutil/8.2.1/fastutil-8.2.1.jar","sha1":"5ad88f325e424f8dbc2be5459e21ea5cab3864e9","size":18800417,"url":"https://libraries.minecraft.net/it/unimi/dsi/fastutil/8.2.1/fastutil-8.2.1.jar"}},"name":"it.unimi.dsi:fastutil:8.2.1"},{"downloads":{"artifact":{"path":"org/apache/logging/log4j/log4j-api/2.8.1/log4j-api-2.8.1.jar","sha1":"e801d13612e22cad62a3f4f3fe7fdbe6334a8e72","size":228859,"url":"https://libraries.minecraft.net/org/apache/logging/log4j/log4j-api/2.8.1/log4j-api-2.8.1.jar"}},"name":"org.apache.logging.log4j:log4j-api:2.8.1"},{"downloads":{"artifact":{"path":"org/apache/logging/log4j/log4j-core/2.8.1/log4j-core-2.8.1.jar","sha1":"4ac28ff2f1ddf05dae3043a190451e8c46b73c31","size":1402925,"url":"https://libraries.minecraft.net/org/apache/logging/log4j/log4j-core/2.8.1/log4j-core-2.8.1.jar"}},"name":"org.apache.logging.log4j:log4j-core:2.8.1"},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1.jar","sha1":"2bb514e444994c6fece99a21f76e0c90438e377f","size":317748,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1.jar"}},"name":"org.lwjgl:lwjgl:3.2.1","rules":[{"action":"allow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2.jar","sha1":"8ad6294407e15780b43e84929c40e4c5e997972e","size":321900,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2.jar"}},"name":"org.lwjgl:lwjgl:3.2.2","rules":[{"action":"allow"},{"action":"disallow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1.jar","sha1":"7a0c583fcbec32b15784f846df536e1837d83666","size":38616,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1.jar"}},"name":"org.lwjgl:lwjgl-jemalloc:3.2.1","rules":[{"action":"allow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2.jar","sha1":"ee8e57a79300f78294576d87c4a587f8c99402e2","size":34848,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2.jar"}},"name":"org.lwjgl:lwjgl-jemalloc:3.2.2","rules":[{"action":"allow"},{"action":"disallow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1.jar","sha1":"dc7ff2dabb40a141ee9bf2e326d9b1b19f3278fb","size":80103,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1.jar"}},"name":"org.lwjgl:lwjgl-openal:3.2.1","rules":[{"action":"allow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2.jar","sha1":"2b772a102b0a11ee5f2109a5b136f4dc7c630827","size":80012,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2.jar"}},"name":"org.lwjgl:lwjgl-openal:3.2.2","rules":[{"action":"allow"},{"action":"disallow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1.jar","sha1":"57008c2374c5bc434b18adfef3f3653ee450ee18","size":931322,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1.jar"}},"name":"org.lwjgl:lwjgl-opengl:3.2.1","rules":[{"action":"allow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2.jar","sha1":"6ac5bb88b44c43ea195a570aab059f63da004cd8","size":929780,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2.jar"}},"name":"org.lwjgl:lwjgl-opengl:3.2.2","rules":[{"action":"allow"},{"action":"disallow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1.jar","sha1":"027abb7f64894b61cad163791acd8113f0b21296","size":116708,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1.jar"}},"name":"org.lwjgl:lwjgl-glfw:3.2.1","rules":[{"action":"allow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2.jar","sha1":"d3ad4df38e400b8afba1de63f84338809399df5b","size":108907,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2.jar"}},"name":"org.lwjgl:lwjgl-glfw:3.2.2","rules":[{"action":"allow"},{"action":"disallow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1.jar","sha1":"31f5eb5fce3791d58ec898bc5c1867d76d781ba1","size":105765,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1.jar"}},"name":"org.lwjgl:lwjgl-stb:3.2.1","rules":[{"action":"allow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2.jar","sha1":"3b8e6ebc5851dd3d17e37e5cadce2eff2a429f0f","size":104469,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2.jar"}},"name":"org.lwjgl:lwjgl-stb:3.2.2","rules":[{"action":"allow"},{"action":"disallow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-tinyfd/3.2.1/lwjgl-tinyfd-3.2.1.jar","sha1":"259f1dbddb921e27e01b32458d6f584eb8bba13a","size":7088,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.1/lwjgl-tinyfd-3.2.1.jar"}},"name":"org.lwjgl:lwjgl-tinyfd:3.2.1","rules":[{"action":"allow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar","sha1":"fcbe606c8f8da6f8f9a05e2c540eb1ee8632b0e9","size":7092,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar"}},"name":"org.lwjgl:lwjgl-tinyfd:3.2.2","rules":[{"action":"allow"},{"action":"disallow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1.jar","sha1":"2bb514e444994c6fece99a21f76e0c90438e377f","size":317748,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1.jar"},"classifiers":{"javadoc":{"path":"org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1-javadoc.jar","sha1":"1f6b7050737559b775d797c0ea56612b8e373fd6","size":1287174,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1-javadoc.jar"},"natives-linux":{"path":"org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1-natives-linux.jar","sha1":"9bdd47cd63ce102cec837a396c8ded597cb75a66","size":87484,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1-natives-linux.jar"},"natives-macos":{"path":"org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1-natives-macos.jar","sha1":"5a4c271d150906858d475603dcb9479453c60555","size":39835,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1-natives-macos.jar"},"natives-windows":{"path":"org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1-natives-windows.jar","sha1":"e799d06b8969db0610e68776e0eff4b6191098bd","size":255871,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1-natives-windows.jar"},"sources":{"path":"org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1-sources.jar","sha1":"106f90ac41449004a969309488aa6e3a2f7d6731","size":255671,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.1/lwjgl-3.2.1-sources.jar"}}},"name":"org.lwjgl:lwjgl:3.2.1","natives":{"osx":"natives-macos"},"rules":[{"action":"allow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2.jar","sha1":"8ad6294407e15780b43e84929c40e4c5e997972e","size":321900,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2.jar"},"classifiers":{"natives-linux":{"path":"org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2-natives-linux.jar","sha1":"ae7976827ca2a3741f6b9a843a89bacd637af350","size":124776,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2-natives-linux.jar"},"natives-macos":{"path":"org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2-natives-macos.jar","sha1":"bbfb75693bdb714c0c69c2c9f9be73d259b43b62","size":48462,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2-natives-macos.jar"},"natives-windows":{"path":"org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2-natives-windows.jar","sha1":"05359f3aa50d36352815fc662ea73e1c00d22170","size":279593,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl/3.2.2/lwjgl-3.2.2-natives-windows.jar"}}},"name":"org.lwjgl:lwjgl:3.2.2","natives":{"linux":"natives-linux","windows":"natives-windows"},"rules":[{"action":"allow"},{"action":"disallow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1.jar","sha1":"7a0c583fcbec32b15784f846df536e1837d83666","size":38616,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1.jar"},"classifiers":{"javadoc":{"path":"org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1-javadoc.jar","sha1":"04f6897be1e2d68bff5ec5e91a2b96e32f084c09","size":461041,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1-javadoc.jar"},"natives-linux":{"path":"org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1-natives-linux.jar","sha1":"5536616b558cea2fea6330ca682fd7c733db9c43","size":156057,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1-natives-linux.jar"},"natives-macos":{"path":"org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1-natives-macos.jar","sha1":"439ab9d0264167a949cc7bcce673704322baaf50","size":117001,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1-natives-macos.jar"},"natives-windows":{"path":"org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1-natives-windows.jar","sha1":"3c869b3d7638c800b7039cd859d064658643ad6e","size":218136,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1-natives-windows.jar"},"sources":{"path":"org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1-sources.jar","sha1":"4450dca46228c02c51bb9bbda70e7cfc3154296d","size":31279,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.1/lwjgl-jemalloc-3.2.1-sources.jar"}}},"name":"org.lwjgl:lwjgl-jemalloc:3.2.1","natives":{"osx":"natives-macos"},"rules":[{"action":"allow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2.jar","sha1":"ee8e57a79300f78294576d87c4a587f8c99402e2","size":34848,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2.jar"},"classifiers":{"natives-linux":{"path":"org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2-natives-linux.jar","sha1":"268c08a150347e04e44ba56e359d62c9b78669df","size":156173,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2-natives-linux.jar"},"natives-macos":{"path":"org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2-natives-macos.jar","sha1":"805f5a10465375ba034b27b72331912fd2846690","size":117127,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2-natives-macos.jar"},"natives-windows":{"path":"org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2-natives-windows.jar","sha1":"338b25b99da3ba5f441f6492f2ce2a9c608860ed","size":220623,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-jemalloc/3.2.2/lwjgl-jemalloc-3.2.2-natives-windows.jar"}}},"name":"org.lwjgl:lwjgl-jemalloc:3.2.2","natives":{"linux":"natives-linux","windows":"natives-windows"},"rules":[{"action":"allow"},{"action":"disallow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1.jar","sha1":"dc7ff2dabb40a141ee9bf2e326d9b1b19f3278fb","size":80103,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1.jar"},"classifiers":{"javadoc":{"path":"org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1-javadoc.jar","sha1":"95752f443686da1b3443e397dc83e730e1907a1e","size":617869,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1-javadoc.jar"},"natives-linux":{"path":"org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1-natives-linux.jar","sha1":"bcd4be67863dd908f696f628c3ca9f6eb9ae5152","size":590716,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1-natives-linux.jar"},"natives-macos":{"path":"org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1-natives-macos.jar","sha1":"9357ebfc82a0d6f64e17093dd963219367cd6fa2","size":528004,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1-natives-macos.jar"},"natives-windows":{"path":"org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1-natives-windows.jar","sha1":"92fb931e65c637cea209ad5c3ffebd1b325ed41d","size":1310083,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1-natives-windows.jar"},"sources":{"path":"org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1-sources.jar","sha1":"8fe3d6e6353685164b1eb3a22980aaa1115d4a32","size":78379,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.1/lwjgl-openal-3.2.1-sources.jar"}}},"name":"org.lwjgl:lwjgl-openal:3.2.1","natives":{"osx":"natives-macos"},"rules":[{"action":"allow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2.jar","sha1":"2b772a102b0a11ee5f2109a5b136f4dc7c630827","size":80012,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2.jar"},"classifiers":{"natives-linux":{"path":"org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2-natives-linux.jar","sha1":"0364f9f5c3947393083ab5f37a571f5603aadd0b","size":590997,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2-natives-linux.jar"},"natives-macos":{"path":"org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2-natives-macos.jar","sha1":"a97b6345d5a9ddf889e262bd7ad8eed43b1bb063","size":528006,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2-natives-macos.jar"},"natives-windows":{"path":"org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2-natives-windows.jar","sha1":"ec20a7d42a2438528fca87e60b1705f1e2339ddb","size":1310102,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-openal/3.2.2/lwjgl-openal-3.2.2-natives-windows.jar"}}},"name":"org.lwjgl:lwjgl-openal:3.2.2","natives":{"linux":"natives-linux","windows":"natives-windows"},"rules":[{"action":"allow"},{"action":"disallow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1.jar","sha1":"57008c2374c5bc434b18adfef3f3653ee450ee18","size":931322,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1.jar"},"classifiers":{"javadoc":{"path":"org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1-javadoc.jar","sha1":"e25fc8cbcbee68182a6b7f13ad71b1f0961005ad","size":4307561,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1-javadoc.jar"},"natives-linux":{"path":"org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1-natives-linux.jar","sha1":"c43bb08ed7dcf1a6d344803e464148b3b14dd274","size":77401,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1-natives-linux.jar"},"natives-macos":{"path":"org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1-natives-macos.jar","sha1":"dca9ad9e59a87172144d531e08ef7f6988073db0","size":38998,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1-natives-macos.jar"},"natives-windows":{"path":"org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1-natives-windows.jar","sha1":"80954961b31084d7b4f2f041d6b5a799a774c880","size":170804,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1-natives-windows.jar"},"sources":{"path":"org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1-sources.jar","sha1":"47930ffbef53c0f45c7e35c01b1c6ad5b2205809","size":1251582,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.1/lwjgl-opengl-3.2.1-sources.jar"}}},"name":"org.lwjgl:lwjgl-opengl:3.2.1","natives":{"osx":"natives-macos"},"rules":[{"action":"allow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2.jar","sha1":"6ac5bb88b44c43ea195a570aab059f63da004cd8","size":929780,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2.jar"},"classifiers":{"natives-linux":{"path":"org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2-natives-linux.jar","sha1":"338d33387919cb3f4cdba143c2b738a71ccfda60","size":77392,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2-natives-linux.jar"},"natives-macos":{"path":"org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2-natives-macos.jar","sha1":"cf4f43e69ee70d8ebfbb6ba93dec9016339e4fdc","size":38989,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2-natives-macos.jar"},"natives-windows":{"path":"org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2-natives-windows.jar","sha1":"d8dcdc91066cae2d2d8279cb4a9f9f05d9525826","size":170798,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-opengl/3.2.2/lwjgl-opengl-3.2.2-natives-windows.jar"}}},"name":"org.lwjgl:lwjgl-opengl:3.2.2","natives":{"linux":"natives-linux","windows":"natives-windows"},"rules":[{"action":"allow"},{"action":"disallow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1.jar","sha1":"027abb7f64894b61cad163791acd8113f0b21296","size":116708,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1.jar"},"classifiers":{"javadoc":{"path":"org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1-javadoc.jar","sha1":"81482a14b617e4fb0c7de69b3e06ef2e28ef894f","size":690774,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1-javadoc.jar"},"natives-linux":{"path":"org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1-natives-linux.jar","sha1":"5a2fb27f9e12a34ecabf6f6a7606c61849e347ee","size":157431,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1-natives-linux.jar"},"natives-macos":{"path":"org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1-natives-macos.jar","sha1":"72fe6dab6110a5a1cd4833f11840eef7b2eadce5","size":64724,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1-natives-macos.jar"},"natives-windows":{"path":"org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1-natives-windows.jar","sha1":"00def7c58ad2e1cb258d6d73be181ffab8ef8bd5","size":265304,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1-natives-windows.jar"},"sources":{"path":"org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1-sources.jar","sha1":"4c56ae817da75996b19601c87d7e759b846c3902","size":101885,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.1/lwjgl-glfw-3.2.1-sources.jar"}}},"name":"org.lwjgl:lwjgl-glfw:3.2.1","natives":{"osx":"natives-macos"},"rules":[{"action":"allow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2.jar","sha1":"d3ad4df38e400b8afba1de63f84338809399df5b","size":108907,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2.jar"},"classifiers":{"natives-linux":{"path":"org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2-natives-linux.jar","sha1":"0957733f26a6661d4883da0335f7ef46d3bbbd7d","size":159198,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2-natives-linux.jar"},"natives-macos":{"path":"org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2-natives-macos.jar","sha1":"98f745038d17ac3192fcd01dc44126b03ec1570d","size":67311,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2-natives-macos.jar"},"natives-windows":{"path":"org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2-natives-windows.jar","sha1":"dc6826d636bf796b33a49038c354210e661bfc17","size":266648,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-glfw/3.2.2/lwjgl-glfw-3.2.2-natives-windows.jar"}}},"name":"org.lwjgl:lwjgl-glfw:3.2.2","natives":{"linux":"natives-linux","windows":"natives-windows"},"rules":[{"action":"allow"},{"action":"disallow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1.jar","sha1":"31f5eb5fce3791d58ec898bc5c1867d76d781ba1","size":105765,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1.jar"},"classifiers":{"javadoc":{"path":"org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1-javadoc.jar","sha1":"524d79537f840d6cfe50e030d24413933f0d464b","size":684972,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1-javadoc.jar"},"natives-linux":{"path":"org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1-natives-linux.jar","sha1":"66e01b8036258619332cb452b970ca0a52db1a87","size":197208,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1-natives-linux.jar"},"natives-macos":{"path":"org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1-natives-macos.jar","sha1":"1f5615c952451c30afafba4a6e3ba4e1cd9e7f5c","size":192364,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1-natives-macos.jar"},"natives-windows":{"path":"org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1-natives-windows.jar","sha1":"d100bfd2b0d03223a043cfcb64a2dfd2bb7f4c61","size":454473,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1-natives-windows.jar"},"sources":{"path":"org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1-sources.jar","sha1":"50ac43d4c6ea5846f354f9576134c0f9264345c2","size":96479,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.1/lwjgl-stb-3.2.1-sources.jar"}}},"name":"org.lwjgl:lwjgl-stb:3.2.1","natives":{"osx":"natives-macos"},"rules":[{"action":"allow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar","sha1":"fcbe606c8f8da6f8f9a05e2c540eb1ee8632b0e9","size":7092,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2.jar"},"classifiers":{"javadoc":{"path":"org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-javadoc.jar","sha1":"ba657a222ee267b75fa81ae5ab29ae29b50f725f","size":368913,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-javadoc.jar"},"natives-linux":{"path":"org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-linux.jar","sha1":"39e35b161c130635d9c8918ce04e887a30c5b687","size":38804,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-linux.jar"},"natives-macos":{"path":"org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-macos.jar","sha1":"46d0798228b8a28e857a2a0f02310fd6ba2a4eab","size":42136,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-macos.jar"},"natives-windows":{"path":"org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-windows.jar","sha1":"e9115958773644e863332a6a06488d26f9e1fc9f","size":208314,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-natives-windows.jar"},"sources":{"path":"org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-sources.jar","sha1":"2fe76dcf2ca02ae0e64ac7c69eb251c09df0e922","size":5034,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.2/lwjgl-tinyfd-3.2.2-sources.jar"}}},"name":"org.lwjgl:lwjgl-tinyfd:3.2.2","natives":{"linux":"natives-linux","windows":"natives-windows"},"rules":[{"action":"allow"},{"action":"disallow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-tinyfd/3.2.1/lwjgl-tinyfd-3.2.1.jar","sha1":"259f1dbddb921e27e01b32458d6f584eb8bba13a","size":7088,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.1/lwjgl-tinyfd-3.2.1.jar"},"classifiers":{"javadoc":{"path":"org/lwjgl/lwjgl-tinyfd/3.2.1/lwjgl-tinyfd-3.2.1-javadoc.jar","sha1":"0a85d995178cdab6b94d9a172dd9e7d2a0d70cfb","size":368913,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.1/lwjgl-tinyfd-3.2.1-javadoc.jar"},"natives-linux":{"path":"org/lwjgl/lwjgl-tinyfd/3.2.1/lwjgl-tinyfd-3.2.1-natives-linux.jar","sha1":"4ad49108397322596d7b85c2c687e5de6ee52157","size":38192,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.1/lwjgl-tinyfd-3.2.1-natives-linux.jar"},"natives-macos":{"path":"org/lwjgl/lwjgl-tinyfd/3.2.1/lwjgl-tinyfd-3.2.1-natives-macos.jar","sha1":"759c2fd9cc5c6ce0b5b7af77ac8200483b7fb660","size":41962,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.1/lwjgl-tinyfd-3.2.1-natives-macos.jar"},"natives-windows":{"path":"org/lwjgl/lwjgl-tinyfd/3.2.1/lwjgl-tinyfd-3.2.1-natives-windows.jar","sha1":"85750d2ca022852e15f58c0b94b3d1d4e7f0ba52","size":207577,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.1/lwjgl-tinyfd-3.2.1-natives-windows.jar"},"sources":{"path":"org/lwjgl/lwjgl-tinyfd/3.2.1/lwjgl-tinyfd-3.2.1-sources.jar","sha1":"c375699fd794c4c87d935e0f9a84e7d80d0de77e","size":5034,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-tinyfd/3.2.1/lwjgl-tinyfd-3.2.1-sources.jar"}}},"name":"org.lwjgl:lwjgl-tinyfd:3.2.1","natives":{"osx":"natives-macos"},"rules":[{"action":"allow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2.jar","sha1":"3b8e6ebc5851dd3d17e37e5cadce2eff2a429f0f","size":104469,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2.jar"},"classifiers":{"natives-linux":{"path":"org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2-natives-linux.jar","sha1":"172c52e586fecf43f759bc4f70a778c01f6fdcc1","size":203476,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2-natives-linux.jar"},"natives-macos":{"path":"org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2-natives-macos.jar","sha1":"ee059b129b09fdecbd8595273926ae930bf5a5d7","size":196796,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2-natives-macos.jar"},"natives-windows":{"path":"org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2-natives-windows.jar","sha1":"811f705cbb29e8ae8d60bdf8fdd38c0c123ad3ef","size":465810,"url":"https://libraries.minecraft.net/org/lwjgl/lwjgl-stb/3.2.2/lwjgl-stb-3.2.2-natives-windows.jar"}}},"name":"org.lwjgl:lwjgl-stb:3.2.2","natives":{"linux":"natives-linux","windows":"natives-windows"},"rules":[{"action":"allow"},{"action":"disallow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"com/mojang/text2speech/1.11.3/text2speech-1.11.3.jar","sha1":"f378f889797edd7df8d32272c06ca80a1b6b0f58","size":13164,"url":"https://libraries.minecraft.net/com/mojang/text2speech/1.11.3/text2speech-1.11.3.jar"}},"name":"com.mojang:text2speech:1.11.3"},{"downloads":{"artifact":{"path":"com/mojang/text2speech/1.11.3/text2speech-1.11.3.jar","sha1":"f378f889797edd7df8d32272c06ca80a1b6b0f58","size":13164,"url":"https://libraries.minecraft.net/com/mojang/text2speech/1.11.3/text2speech-1.11.3.jar"},"classifiers":{"natives-linux":{"path":"com/mojang/text2speech/1.11.3/text2speech-1.11.3-natives-linux.jar","sha1":"ac641755a2a841d1fca9e660194f42523ee5cfe0","size":7833,"url":"https://libraries.minecraft.net/com/mojang/text2speech/1.11.3/text2speech-1.11.3-natives-linux.jar"},"natives-windows":{"path":"com/mojang/text2speech/1.11.3/text2speech-1.11.3-natives-windows.jar","sha1":"c0b242c0091be5acbf303263c7eeeaedd70544c7","size":81379,"url":"https://libraries.minecraft.net/com/mojang/text2speech/1.11.3/text2speech-1.11.3-natives-windows.jar"},"sources":{"path":"com/mojang/text2speech/1.11.3/text2speech-1.11.3-sources.jar","sha1":"772a37dd77417571e6f119a8d306f0c14c2ee410","size":5332,"url":"https://libraries.minecraft.net/com/mojang/text2speech/1.11.3/text2speech-1.11.3-sources.jar"}}},"extract":{"exclude":["META-INF/"]},"name":"com.mojang:text2speech:1.11.3","natives":{"linux":"natives-linux","windows":"natives-windows"}},{"downloads":{"artifact":{"path":"ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar","sha1":"6ef160c3133a78de015830860197602ca1c855d3","size":40502,"url":"https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar"},"classifiers":{"javadoc":{"path":"ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-javadoc.jar","sha1":"fb0092f22cb4fe8e631452f577b7a238778abf2a","size":174060,"url":"https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-javadoc.jar"},"natives-osx":{"path":"ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-natives-osx.jar","sha1":"08befab4894d55875f33c3d300f4f71e6e828f64","size":5629,"url":"https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-natives-osx.jar"},"sources":{"path":"ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-sources.jar","sha1":"865837a198189aee737019561ece842827f24278","size":43283,"url":"https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0-sources.jar"}}},"extract":{"exclude":["META-INF/"]},"name":"ca.weblite:java-objc-bridge:1.0.0","natives":{"osx":"natives-osx"},"rules":[{"action":"allow","os":{"name":"osx"}}]},{"downloads":{"artifact":{"path":"ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar","sha1":"6ef160c3133a78de015830860197602ca1c855d3","size":40502,"url":"https://libraries.minecraft.net/ca/weblite/java-objc-bridge/1.0.0/java-objc-bridge-1.0.0.jar"}},"name":"ca.weblite:java-objc-bridge:1.0.0","rules":[{"action":"allow","os":{"name":"osx"}}]}] + * logging : + * {"client":{"argument":"-Dlog4j.configurationFile=${path}","file":{"id":"client-1.12.xml","sha1":"ef4f57b922df243d0cef096efe808c72db042149","size":877,"url":"https://launcher.mojang.com/v1/objects/ef4f57b922df243d0cef096efe808c72db042149/client-1.12.xml"},"type":"log4j2-xml"}} + * mainClass : net.minecraft.client.main.Main minimumLauncherVersion : 21 releaseTime : + * 2019-12-16T10:29:47+00:00 time : 2019-12-16T10:29:47+00:00 type : release + */ + private ArgumentsBean arguments; + + private AssetIndexBean assetIndex; + + private String assets; + + private DownloadsBean downloads; + + private String id; + + private LoggingBean logging; + + private String mainClass; + + private int minimumLauncherVersion; + + private String releaseTime; + + private String time; + + private String type; + + private List libraries; + + public ArgumentsBean getArguments() { + return arguments; + } + + public void setArguments(ArgumentsBean arguments) { + this.arguments = arguments; + } + + public AssetIndexBean getAssetIndex() { + return assetIndex; + } + + public void setAssetIndex(AssetIndexBean assetIndex) { + this.assetIndex = assetIndex; + } + + public String getAssets() { + return assets; + } + + public void setAssets(String assets) { + this.assets = assets; + } + + public DownloadsBean getDownloads() { + return downloads; + } + + public void setDownloads(DownloadsBean downloads) { + this.downloads = downloads; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public LoggingBean getLogging() { + return logging; + } + + public void setLogging(LoggingBean logging) { + this.logging = logging; + } + + public String getMainClass() { + return mainClass; + } + + public void setMainClass(String mainClass) { + this.mainClass = mainClass; + } + + public int getMinimumLauncherVersion() { + return minimumLauncherVersion; + } + + public void setMinimumLauncherVersion(int minimumLauncherVersion) { + this.minimumLauncherVersion = minimumLauncherVersion; + } + + public String getReleaseTime() { + return releaseTime; + } + + public void setReleaseTime(String releaseTime) { + this.releaseTime = releaseTime; + } + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public List getLibraries() { + return libraries; + } + + public void setLibraries(List libraries) { + this.libraries = libraries; + } + + public static class ArgumentsBean { + private List game; + + private List jvm; + + public List getGame() { + return game; + } + + public void setGame(List game) { + this.game = game; + } + + public List getJvm() { + return jvm; + } + + public void setJvm(List jvm) { + this.jvm = jvm; + } + + public static class JvmBean { + private List rules; + + private List value; + + public List getRules() { + return rules; + } + + public void setRules(List rules) { + this.rules = rules; + } + + public List getValue() { + return value; + } + + public void setValue(List value) { + this.value = value; + } + + public static class RulesBean { + /** + * action : allow os : {"name":"osx"} + */ + private String action; + + private OsBean os; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public OsBean getOs() { + return os; + } + + public void setOs(OsBean os) { + this.os = os; + } + + public static class OsBean { + /** + * name : osx + */ + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + + } + + } + + } + + public static class AssetIndexBean { + /** + * id : 1.15 sha1 : 62745391056f1d0e1ffc808a0d4f0145b668ca24 size : 234874 totalSize : 216306372 + * url : + * https://launchermeta.mojang.com/v1/packages/62745391056f1d0e1ffc808a0d4f0145b668ca24/1.15.json + */ + private String id; + + private String sha1; + + private int size; + + private int totalSize; + + private String url; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getSha1() { + return sha1; + } + + public void setSha1(String sha1) { + this.sha1 = sha1; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public int getTotalSize() { + return totalSize; + } + + public void setTotalSize(int totalSize) { + this.totalSize = totalSize; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + } + + public static class DownloadsBean { + /** + * client : + * {"sha1":"8b11614bea9293592a947ea8f4fd72981ea66677","size":15518397,"url":"https://launcher.mojang.com/v1/objects/8b11614bea9293592a947ea8f4fd72981ea66677/client.jar"} + * client_mappings : + * {"sha1":"cc77cb804c2cc0fa151b0745df4c5de8e64d1bb5","size":4962913,"url":"https://launcher.mojang.com/v1/objects/cc77cb804c2cc0fa151b0745df4c5de8e64d1bb5/client.txt"} + * server : + * {"sha1":"4d1826eebac84847c71a77f9349cc22afd0cf0a1","size":36164938,"url":"https://launcher.mojang.com/v1/objects/4d1826eebac84847c71a77f9349cc22afd0cf0a1/server.jar"} + * server_mappings : + * {"sha1":"47f8a03f5492223753f5f2b531d4938813903684","size":3730004,"url":"https://launcher.mojang.com/v1/objects/47f8a03f5492223753f5f2b531d4938813903684/server.txt"} + */ + private ClientBean client; + + private ClientMappingsBean client_mappings; + + private ServerBean server; + + private ServerMappingsBean server_mappings; + + public ClientBean getClient() { + return client; + } + + public void setClient(ClientBean client) { + this.client = client; + } + + public ClientMappingsBean getClient_mappings() { + return client_mappings; + } + + public void setClient_mappings(ClientMappingsBean client_mappings) { + this.client_mappings = client_mappings; + } + + public ServerBean getServer() { + return server; + } + + public void setServer(ServerBean server) { + this.server = server; + } + + public ServerMappingsBean getServer_mappings() { + return server_mappings; + } + + public void setServer_mappings(ServerMappingsBean server_mappings) { + this.server_mappings = server_mappings; + } + + public static class ClientBean { + /** + * sha1 : 8b11614bea9293592a947ea8f4fd72981ea66677 size : 15518397 url : + * https://launcher.mojang.com/v1/objects/8b11614bea9293592a947ea8f4fd72981ea66677/client.jar + */ + private String sha1; + + private int size; + + private String url; + + public String getSha1() { + return sha1; + } + + public void setSha1(String sha1) { + this.sha1 = sha1; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + } + + public static class ClientMappingsBean { + /** + * sha1 : cc77cb804c2cc0fa151b0745df4c5de8e64d1bb5 size : 4962913 url : + * https://launcher.mojang.com/v1/objects/cc77cb804c2cc0fa151b0745df4c5de8e64d1bb5/client.txt + */ + private String sha1; + + private int size; + + private String url; + + public String getSha1() { + return sha1; + } + + public void setSha1(String sha1) { + this.sha1 = sha1; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + } + + public static class ServerBean { + /** + * sha1 : 4d1826eebac84847c71a77f9349cc22afd0cf0a1 size : 36164938 url : + * https://launcher.mojang.com/v1/objects/4d1826eebac84847c71a77f9349cc22afd0cf0a1/server.jar + */ + private String sha1; + + private int size; + + private String url; + + public String getSha1() { + return sha1; + } + + public void setSha1(String sha1) { + this.sha1 = sha1; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + } + + public static class ServerMappingsBean { + /** + * sha1 : 47f8a03f5492223753f5f2b531d4938813903684 size : 3730004 url : + * https://launcher.mojang.com/v1/objects/47f8a03f5492223753f5f2b531d4938813903684/server.txt + */ + private String sha1; + + private int size; + + private String url; + + public String getSha1() { + return sha1; + } + + public void setSha1(String sha1) { + this.sha1 = sha1; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + } + + } + + public static class LoggingBean { + /** + * client : + * {"argument":"-Dlog4j.configurationFile=${path}","file":{"id":"client-1.12.xml","sha1":"ef4f57b922df243d0cef096efe808c72db042149","size":877,"url":"https://launcher.mojang.com/v1/objects/ef4f57b922df243d0cef096efe808c72db042149/client-1.12.xml"},"type":"log4j2-xml"} + */ + private ClientBeanX client; + + public ClientBeanX getClient() { + return client; + } + + public void setClient(ClientBeanX client) { + this.client = client; + } + + public static class ClientBeanX { + /** + * argument : -Dlog4j.configurationFile=${path} file : + * {"id":"client-1.12.xml","sha1":"ef4f57b922df243d0cef096efe808c72db042149","size":877,"url":"https://launcher.mojang.com/v1/objects/ef4f57b922df243d0cef096efe808c72db042149/client-1.12.xml"} + * type : log4j2-xml + */ + private String argument; + + private FileBean file; + + private String type; + + public String getArgument() { + return argument; + } + + public void setArgument(String argument) { + this.argument = argument; + } + + public FileBean getFile() { + return file; + } + + public void setFile(FileBean file) { + this.file = file; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public static class FileBean { + /** + * id : client-1.12.xml sha1 : ef4f57b922df243d0cef096efe808c72db042149 size : 877 url : + * https://launcher.mojang.com/v1/objects/ef4f57b922df243d0cef096efe808c72db042149/client-1.12.xml + */ + private String id; + + private String sha1; + + private int size; + + private String url; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getSha1() { + return sha1; + } + + public void setSha1(String sha1) { + this.sha1 = sha1; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + } + + } + + } + + public static class LibrariesBean { + /** + * downloads : + * {"artifact":{"path":"com/mojang/patchy/1.1/patchy-1.1.jar","sha1":"aef610b34a1be37fa851825f12372b78424d8903","size":15817,"url":"https://libraries.minecraft.net/com/mojang/patchy/1.1/patchy-1.1.jar"}} + * name : com.mojang:patchy:1.1 rules : [{"action":"allow","os":{"name":"osx"}}] natives : + * {"osx":"natives-macos"} extract : {"exclude":["META-INF/"]} + */ + private DownloadsBeanX downloads; + + private String name; + + private NativesBean natives; + + private ExtractBean extract; + + private List rules; + + public DownloadsBeanX getDownloads() { + return downloads; + } + + public void setDownloads(DownloadsBeanX downloads) { + this.downloads = downloads; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public NativesBean getNatives() { + return natives; + } + + public void setNatives(NativesBean natives) { + this.natives = natives; + } + + public ExtractBean getExtract() { + return extract; + } + + public void setExtract(ExtractBean extract) { + this.extract = extract; + } + + public List getRules() { + return rules; + } + + public void setRules(List rules) { + this.rules = rules; + } + + public static class DownloadsBeanX { + /** + * artifact : + * {"path":"com/mojang/patchy/1.1/patchy-1.1.jar","sha1":"aef610b34a1be37fa851825f12372b78424d8903","size":15817,"url":"https://libraries.minecraft.net/com/mojang/patchy/1.1/patchy-1.1.jar"} + */ + private ArtifactBean artifact; + + public ArtifactBean getArtifact() { + return artifact; + } + + public void setArtifact(ArtifactBean artifact) { + this.artifact = artifact; + } + + public static class ArtifactBean { + /** + * path : com/mojang/patchy/1.1/patchy-1.1.jar sha1 : + * aef610b34a1be37fa851825f12372b78424d8903 size : 15817 url : + * https://libraries.minecraft.net/com/mojang/patchy/1.1/patchy-1.1.jar + */ + private String path; + + private String sha1; + + private int size; + + private String url; + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getSha1() { + return sha1; + } + + public void setSha1(String sha1) { + this.sha1 = sha1; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + } + + } + + public static class NativesBean { + /** + * osx : natives-macos + */ + private String osx; + + public String getOsx() { + return osx; + } + + public void setOsx(String osx) { + this.osx = osx; + } + + } + + public static class ExtractBean { + private List exclude; + + public List getExclude() { + return exclude; + } + + public void setExclude(List exclude) { + this.exclude = exclude; + } + + } + + public static class RulesBeanX { + /** + * action : allow os : {"name":"osx"} + */ + private String action; + + private OsBeanX os; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public OsBeanX getOs() { + return os; + } + + public void setOs(OsBeanX os) { + this.os = os; + } + + public static class OsBeanX { + /** + * name : osx + */ + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + + } + + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/VersionList.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/VersionList.java new file mode 100644 index 0000000..d4dbe8b --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/mojangapi/VersionList.java @@ -0,0 +1,158 @@ +/* + * This file is a part of project QuickShop, the name is VersionList.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util.mojangapi; + +import java.util.List; + +public class VersionList { + + /** + * latest : {"release":"1.15.1","snapshot":"1.15.1"} versions : + * [{"id":"1.15.1","type":"release","url":"https://launchermeta.mojang.com/v1/packages/57c1b5f7376febf269f7e555f96def8f1a43bb76/1.15.1.json","time":"2019-12-16T10:33:36+00:00","releaseTime":"2019-12-16T10:29:47+00:00"},{"id":"1.15.1-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/d239ea078ac8b83a3c8d58fa4350aa11ce846884/1.15.1-pre1.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-12-12T14:02:30+00:00"},{"id":"1.15","type":"release","url":"https://launchermeta.mojang.com/v1/packages/443d30b7da718d9aa87d3f3c0c899d396658f709/1.15.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-12-09T13:13:38+00:00"},{"id":"1.15-pre7","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/58607dd6ec06293aaa114637252bdacabaeabdeb/1.15-pre7.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-12-09T12:14:11+00:00"},{"id":"1.15-pre6","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/5321d1761f24669cdbf3b150935891c5959df1d0/1.15-pre6.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-12-06T12:04:30+00:00"},{"id":"1.15-pre5","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/333c5fabcd618c8ac91be79d694f6907450cbf78/1.15-pre5.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-12-05T13:20:00+00:00"},{"id":"1.15-pre4","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ddc2328ebbca2cecae0466f4ea25599b93efbb21/1.15-pre4.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-12-03T12:24:24+00:00"},{"id":"1.15-pre3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/8a74cef7b525cc02c4c44dd5d56d3cac1ea67413/1.15-pre3.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-11-28T17:17:50+00:00"},{"id":"1.15-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/4c41453e6c92ca22007e16a167010c2f9b692bc1/1.15-pre2.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-11-25T18:09:38+00:00"},{"id":"1.15-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/d0875206ed354177e6a33b0d8cb819d5fa995fbe/1.15-pre1.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-11-21T17:01:17+00:00"},{"id":"19w46b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/115d0942f228e3cb4e6552dfcf17ea97ab1de2cb/19w46b.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-11-14T13:29:24+00:00"},{"id":"19w46a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/8885f644826cb7efb2bc5fde58bf7eb5ca7a7200/19w46a.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-11-13T16:37:46+00:00"},{"id":"19w45b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/51a441c591c863e6de37ef4a176a02803ed0bc67/19w45b.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-11-08T12:42:44+00:00"},{"id":"19w45a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/206af9f137dd4f7cc29250375985e8702a7de227/19w45a.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-11-07T16:19:20+00:00"},{"id":"19w44a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/d834604fac8cd74dcf40a4445571b538500a2db6/19w44a.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-10-30T15:31:44+00:00"},{"id":"19w42a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/c4e966161b97320d728f1789d55e0fd18214e29e/19w42a.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-10-16T15:30:39+00:00"},{"id":"19w41a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/7187270992ac12c58e284abc520939e36217f69d/19w41a.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-10-09T15:21:35+00:00"},{"id":"19w40a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f4eaa67b689254368bb98430efd7f58ff48cc919/19w40a.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-10-02T13:40:26+00:00"},{"id":"19w39a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/380fc859577e4e2de5265fa757e722c706343557/19w39a.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-09-27T10:13:33+00:00"},{"id":"19w38b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/68527e31bcaa07afb63518cec727ffc28a0d2eac/19w38b.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-09-18T14:59:13+00:00"},{"id":"19w38a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/9d7951d20d310617748c1419c9bd8018e1248dd6/19w38a.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-09-18T10:03:22+00:00"},{"id":"19w37a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/39e4f1ed9ac6e84b8e1f357f28eb3d44d346217e/19w37a.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-09-11T11:46:44+00:00"},{"id":"19w36a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/0c3334342c489e505e80a419d2f1e3c9b1e3b605/19w36a.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-09-04T11:19:34+00:00"},{"id":"19w35a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2579841485ad30da666a2339536a97e3a7a9e69a/19w35a.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-08-28T15:01:44+00:00"},{"id":"19w34a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/8bdea001152f26a7d01cb52985a2a5692ec3896d/19w34a.json","time":"2019-12-16T09:54:41+00:00","releaseTime":"2019-08-22T12:06:21+00:00"},{"id":"1.14.4","type":"release","url":"https://launchermeta.mojang.com/v1/packages/74b5fb5fa9ec7b14abe60b468e40703cfbf8d10e/1.14.4.json","time":"2019-09-04T14:37:30+00:00","releaseTime":"2019-07-19T09:25:47+00:00"},{"id":"1.14.4-pre7","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/c69051042abf0340dce2e00723902e85a3d23d12/1.14.4-pre7.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-07-18T11:32:36+00:00"},{"id":"1.14.4-pre6","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/10213c3e0c7e9954ba157d4e8ebe08367802ca53/1.14.4-pre6.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-07-15T12:39:49+00:00"},{"id":"1.14.4-pre5","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/cef180973086805b5e8618426ec82d29a367cf34/1.14.4-pre5.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-07-11T10:52:33+00:00"},{"id":"1.14.4-pre4","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ee6105b0d0b709cd9d623e1bb4a1879ceaabbcb7/1.14.4-pre4.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-07-10T12:53:29+00:00"},{"id":"1.14.4-pre3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/0f2f3e7780c055bf8beb3d60e8e5d558f6f9058e/1.14.4-pre3.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-07-08T11:21:42+00:00"},{"id":"1.14.4-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/3b8c4c8f5620a978240911a6d1a996d42c29092a/1.14.4-pre2.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-07-04T14:41:05+00:00"},{"id":"1.14.4-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/68e2ca4e113772dc0bb35071852df729bbb08da9/1.14.4-pre1.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-07-03T13:01:01+00:00"},{"id":"1.14.3","type":"release","url":"https://launchermeta.mojang.com/v1/packages/771d2feb29736889b66632f037e973fbf73063f7/1.14.3.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-06-24T12:52:52+00:00"},{"id":"1.14.3-pre4","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/d6a23c6a700a312c69a91d9608ca85cc5f5d6a2b/1.14.3-pre4.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-06-19T11:44:29+00:00"},{"id":"1.14.3-pre3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/767d65ec7037b0b46300e720fd3f2bf56afad1c6/1.14.3-pre3.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-06-14T08:03:33+00:00"},{"id":"1.14.3-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2d3239cccc4ed0e4bcf20796584cda2c2716dd9a/1.14.3-pre2.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-06-07T09:11:29+00:00"},{"id":"1.14.3-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/baa80fcf68d12f216514d83abb5513414a733826/1.14.3-pre1.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-06-03T14:34:20+00:00"},{"id":"1.14.2","type":"release","url":"https://launchermeta.mojang.com/v1/packages/2a74bf61101997340b101677434b36c29af68bd7/1.14.2.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-05-27T11:48:25+00:00"},{"id":"1.14.2 + * Pre-Release + * 4","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/89149d5106f7b2558c47806205797ca7e3effd80/1.14.2_Pre-Release_4.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-05-27T07:21:11+00:00"},{"id":"1.14.2 + * Pre-Release + * 3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f827544a1a417c4d9330c6c41d6af747957c79ec/1.14.2_Pre-Release_3.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-05-22T13:12:51+00:00"},{"id":"1.14.2 + * Pre-Release + * 2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b7b6d4a6f88a1782d065775f67e71cfb83b36ab1/1.14.2_Pre-Release_2.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-05-17T12:21:03+00:00"},{"id":"1.14.2 + * Pre-Release + * 1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/9eec5760b10ee665d666c0b04fcacff4255e914b/1.14.2_Pre-Release_1.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-05-16T15:40:25+00:00"},{"id":"1.14.1","type":"release","url":"https://launchermeta.mojang.com/v1/packages/6997d2f2872eb815df5b5cdcdd17a29f80eab844/1.14.1.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-05-13T11:10:12+00:00"},{"id":"1.14.1 + * Pre-Release + * 2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/6fda8188f21f393a9462128ee125411d54baa908/1.14.1_Pre-Release_2.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-05-09T14:01:04+00:00"},{"id":"1.14.1 + * Pre-Release + * 1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/03a18eb4d99c1a5e850ed179052ace5062149bb8/1.14.1_Pre-Release_1.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-05-07T14:44:42+00:00"},{"id":"1.14","type":"release","url":"https://launchermeta.mojang.com/v1/packages/002290f18faa9f4d7e239436d2056a4812cb7cc6/1.14.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-04-23T14:52:44+00:00"},{"id":"1.14 + * Pre-Release + * 5","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/62026af356e1b48bc427c6a73873c594ecb6b2fb/1.14_Pre-Release_5.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-04-18T11:05:19+00:00"},{"id":"1.14 + * Pre-Release + * 4","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/19b39d3e804b615350f6c163c592b5dfbcbf4e8d/1.14_Pre-Release_4.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-04-17T15:31:12+00:00"},{"id":"1.14 + * Pre-Release + * 3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/5a3639c873d18fe32ce0a5553d355689c88b67b7/1.14_Pre-Release_3.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-04-16T13:57:10+00:00"},{"id":"1.14 + * Pre-Release + * 2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/4b92b935382f7e1647b70ffec52009b8e67cb446/1.14_Pre-Release_2.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-04-12T11:38:53+00:00"},{"id":"1.14 + * Pre-Release + * 1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/4fc583e3bc5a2b7175c82b7d013d0c9a04571ea1/1.14_Pre-Release_1.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-04-10T14:24:16+00:00"},{"id":"19w14b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2a3c391a8119cef86cf1fb3e434bb63f044092aa/19w14b.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-04-05T10:33:58+00:00"},{"id":"19w14a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/23646f8e0a8205952654ef418fec9e1d696f9083/19w14a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-04-03T13:45:00+00:00"},{"id":"3D + * Shareware + * v1.34","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/14b4bda35d123bb53313ce099943d40cf25fc159/3D_Shareware_v1.34.json","time":"2019-06-28T07:12:23+00:00","releaseTime":"2019-04-01T11:18:08+00:00"},{"id":"19w13b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/9352276bd2110a6df9265446c6899c5e1865bc0c/19w13b.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-03-29T16:53:22+00:00"},{"id":"19w13a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/72493359732d7cdf6410695428f6f7b81b50a2cb/19w13a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-03-27T15:15:31+00:00"},{"id":"19w12b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/5c7226b97b2f2cd1f86d7bacae10b990fc3412e0/19w12b.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-03-21T15:20:01+00:00"},{"id":"19w12a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b4edadb2712470a48a25f908b28d8a66a5144866/19w12a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-03-20T16:47:34+00:00"},{"id":"19w11b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/020980042400c4226cc131666da4782baa7f660a/19w11b.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-03-14T14:26:23+00:00"},{"id":"19w11a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/16c393fa7eda1447e5c43ff8a9237f5666a5c0dd/19w11a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-03-13T13:59:29+00:00"},{"id":"19w09a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/828559d2e7690f2e0d33b3943712ac8b8e6bf862/19w09a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-02-27T14:44:30+00:00"},{"id":"19w08b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/c15af31e0571ee01c988425af23587d65aa5aeff/19w08b.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-02-21T13:38:09+00:00"},{"id":"19w08a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/bcd1dea72c2e2b4d4d9f227be1a9cc07b2ec14c4/19w08a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-02-20T14:56:58+00:00"},{"id":"19w07a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/80431007ce6851d5a6ea8f2348aefac23fc41618/19w07a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-02-13T16:12:08+00:00"},{"id":"19w06a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ecb34b3150dc1bd72b429f337c76a70ef77630ef/19w06a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-02-06T16:24:13+00:00"},{"id":"19w05a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f2108d2472d48fe1bc5cf0d8d3b00c4c9c2dec80/19w05a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-01-30T15:16:49+00:00"},{"id":"19w04b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/990653458a48112ae3b64908effd267c1538edc9/19w04b.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-01-25T12:20:15+00:00"},{"id":"19w04a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a65141d2eabffc56f646cfc87da51b10c85c974c/19w04a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-01-24T15:31:52+00:00"},{"id":"19w03c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/8ca46d174fcf38e99af824ad8538b191342e6637/19w03c.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-01-18T11:27:13+00:00"},{"id":"19w03b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/395a5d3ec0cb38863ce1f0aef9f5e2ce22405d65/19w03b.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-01-17T16:43:27+00:00"},{"id":"19w03a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/41031c5cfcc8e70e57b44d88c3ff96dced3ec30b/19w03a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-01-16T16:45:02+00:00"},{"id":"19w02a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/3ed68601a666b3d5be95d1a49d3b44f0deebf43b/19w02a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2019-01-09T15:52:07+00:00"},{"id":"18w50a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2594693caaa86414767de59b8fd7674c9b97dc58/18w50a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2018-12-12T14:58:13+00:00"},{"id":"18w49a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/8c1c91caaddbb133b328e4fdb22e7a3e758b4d94/18w49a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2018-12-05T12:24:30+00:00"},{"id":"18w48b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/71b4de2f93861ddbe6ef9deb645aed66afd0f5cc/18w48b.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2018-11-30T10:37:31+00:00"},{"id":"18w48a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/d3cabeaff421b29cfabd1ed3358b6be1d700357b/18w48a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2018-11-29T13:11:38+00:00"},{"id":"18w47b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/7033ba9ea26e84f7383457dfe12519fa943b302e/18w47b.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2018-11-23T10:46:41+00:00"},{"id":"18w47a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/bc43796e1d44b38495ce7006f4e1b0efdae221fe/18w47a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2018-11-21T15:45:22+00:00"},{"id":"18w46a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/10272603c082dd98192aa05a7e4ee22c6a874b9d/18w46a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2018-11-15T13:43:14+00:00"},{"id":"18w45a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/71db320cff7a34460bb108aaa0666c85ec3fe7de/18w45a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2018-11-07T14:40:06+00:00"},{"id":"18w44a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/d415d669f31e322f09598464c182b63e9c1ac8c9/18w44a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2018-10-31T15:29:16+00:00"},{"id":"18w43c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/9fbf22d3bb1adcd6707f5a4d5cabc4f3cb5ca29c/18w43c.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2018-10-26T08:40:46+00:00"},{"id":"18w43b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/e44e8de646c82a9705bc4098cbe0698bd434bcc5/18w43b.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2018-10-24T15:02:30+00:00"},{"id":"18w43a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/7e4be17caa10c2ee677e8f30cfa1e65e766df93a/18w43a.json","time":"2019-08-22T12:46:36+00:00","releaseTime":"2018-10-24T10:52:16+00:00"},{"id":"1.13.2","type":"release","url":"https://launchermeta.mojang.com/v1/packages/26ec75fc9a8b990fa976100a211475d18bd97de0/1.13.2.json","time":"2019-06-28T07:06:03+00:00","releaseTime":"2018-10-22T11:41:07+00:00"},{"id":"1.13.2-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/cb351ca02354abfd0c5280b083b20dac6d9d73ee/1.13.2-pre2.json","time":"2019-06-28T07:07:16+00:00","releaseTime":"2018-10-18T14:46:12+00:00"},{"id":"1.13.2-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/32161e5684d156915330b430af7b77d0bf415896/1.13.2-pre1.json","time":"2019-06-28T07:07:14+00:00","releaseTime":"2018-10-16T13:40:58+00:00"},{"id":"1.13.1","type":"release","url":"https://launchermeta.mojang.com/v1/packages/2553b0a630e1d1676d932394866e4f1621a59fad/1.13.1.json","time":"2019-06-28T07:06:01+00:00","releaseTime":"2018-08-22T14:03:42+00:00"},{"id":"1.13.1-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/5432798617e434ec9e061b8e9461afc3df98b45f/1.13.1-pre2.json","time":"2019-06-28T07:07:12+00:00","releaseTime":"2018-08-20T13:52:09+00:00"},{"id":"1.13.1-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/3f47a3acd1d8775478143385569355a3ec30ea69/1.13.1-pre1.json","time":"2019-06-28T07:07:11+00:00","releaseTime":"2018-08-16T13:08:44+00:00"},{"id":"18w33a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/d77ff33b5a07f400ccf7483e60921143948e3412/18w33a.json","time":"2019-06-28T07:11:06+00:00","releaseTime":"2018-08-15T14:28:56+00:00"},{"id":"18w32a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/9dc8e10605ab503ae1b5eefbc31e376d2d2d7735/18w32a.json","time":"2019-06-28T07:11:04+00:00","releaseTime":"2018-08-08T13:16:57+00:00"},{"id":"18w31a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b538d9e8bb8a82e96dd02ab00a5962602d0accfe/18w31a.json","time":"2019-06-28T07:11:02+00:00","releaseTime":"2018-08-01T12:54:44+00:00"},{"id":"18w30b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/c475ca09f640fdaf7ac7972a8ab1c6be10609052/18w30b.json","time":"2019-06-28T07:11:00+00:00","releaseTime":"2018-07-26T16:06:57+00:00"},{"id":"18w30a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/247f631e4fc91d4e76ff06daa3750228599b6733/18w30a.json","time":"2019-06-28T07:10:58+00:00","releaseTime":"2018-07-25T14:29:31+00:00"},{"id":"1.13","type":"release","url":"https://launchermeta.mojang.com/v1/packages/1efd5dfcae060b847706500e408a76674922de89/1.13.json","time":"2019-06-28T07:06:04+00:00","releaseTime":"2018-07-18T15:11:46+00:00"},{"id":"1.13-pre10","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/7a5c5769e1c420db177040c33a4516515bdc3e55/1.13-pre10.json","time":"2019-06-28T07:06:50+00:00","releaseTime":"2018-07-17T14:48:06+00:00"},{"id":"1.13-pre9","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b54392801613930233d5f96b44662729bf23f7e0/1.13-pre9.json","time":"2019-06-28T07:07:08+00:00","releaseTime":"2018-07-16T14:17:42+00:00"},{"id":"1.13-pre8","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/aa97bdcf593e6ff67b0b044590eae96ac81c5572/1.13-pre8.json","time":"2019-06-28T07:07:06+00:00","releaseTime":"2018-07-13T11:45:00+00:00"},{"id":"1.13-pre7","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/dec652f76a03e192b7b8de0e093869ca803eb4c8/1.13-pre7.json","time":"2019-06-28T07:07:04+00:00","releaseTime":"2018-07-10T14:21:42+00:00"},{"id":"1.13-pre6","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/75e367814db76567ca02da12c80246cd22935111/1.13-pre6.json","time":"2019-06-28T07:07:02+00:00","releaseTime":"2018-07-04T12:36:00+00:00"},{"id":"1.13-pre5","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b5f4b7d67e57a2784204af0c744e6bfb02a5f04f/1.13-pre5.json","time":"2019-06-28T07:06:59+00:00","releaseTime":"2018-06-28T13:58:53+00:00"},{"id":"1.13-pre4","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/aca7f5d7d13b996eeaf6f186d208769f18bdb04c/1.13-pre4.json","time":"2019-06-28T07:06:57+00:00","releaseTime":"2018-06-26T13:00:55+00:00"},{"id":"1.13-pre3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/06c31253996b4de3188705e3d6c33577d1f9a305/1.13-pre3.json","time":"2019-06-28T07:06:55+00:00","releaseTime":"2018-06-21T12:57:11+00:00"},{"id":"1.13-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/05ba232797b3cf7fa2ac879624a7b5de1d6651bd/1.13-pre2.json","time":"2019-06-28T07:06:53+00:00","releaseTime":"2018-06-15T09:20:00+00:00"},{"id":"1.13-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a4d5660628eba8143c723ff40112006365d02f1d/1.13-pre1.json","time":"2019-06-28T07:06:48+00:00","releaseTime":"2018-06-04T15:17:34+00:00"},{"id":"18w22c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/27a99c8d0f2a998a3fedb180804a16f2bf99b95f/18w22c.json","time":"2019-06-28T07:10:56+00:00","releaseTime":"2018-05-31T13:53:15+00:00"},{"id":"18w22b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/0aa1569c658a410cb2f83d1b052635d7e8392683/18w22b.json","time":"2019-06-28T07:10:54+00:00","releaseTime":"2018-05-30T13:48:58+00:00"},{"id":"18w22a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a8d3d3213543f0465d5f465f8c1e80a2957eefa3/18w22a.json","time":"2019-06-28T07:10:52+00:00","releaseTime":"2018-05-29T13:23:55+00:00"},{"id":"18w21b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/e898f26c0a93e726836fd16d89df63837e6eee82/18w21b.json","time":"2019-06-28T07:10:50+00:00","releaseTime":"2018-05-25T10:09:09+00:00"},{"id":"18w21a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/7cdac8c7c494291a01f151a5dc146f38a70c4a2b/18w21a.json","time":"2019-06-28T07:10:48+00:00","releaseTime":"2018-05-23T13:11:49+00:00"},{"id":"18w20c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a7e08d32440189aa8e10f0abaf7a4fa0c9e8afc1/18w20c.json","time":"2019-06-28T07:10:46+00:00","releaseTime":"2018-05-17T14:06:56+00:00"},{"id":"18w20b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/86e70871ca7a1b6d2ffa33cd8df79357a29dfb5e/18w20b.json","time":"2019-06-28T07:10:45+00:00","releaseTime":"2018-05-16T14:35:35+00:00"},{"id":"18w20a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a64998fc7679c161aa9dd671bec77329dd68e2cc/18w20a.json","time":"2019-06-28T07:10:43+00:00","releaseTime":"2018-05-15T14:02:25+00:00"},{"id":"18w19b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/dfdacf219ef2d126416e8c9e3d08feeb244a8a49/18w19b.json","time":"2019-06-28T07:10:41+00:00","releaseTime":"2018-05-09T10:00:51+00:00"},{"id":"18w19a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/cc868f094a6cdec8e1a24ed90dde12c8006e308c/18w19a.json","time":"2019-06-28T07:10:39+00:00","releaseTime":"2018-05-08T13:05:19+00:00"},{"id":"18w16a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/97812ee3d6cc39ed5d0eb8193704691480bdf3b1/18w16a.json","time":"2019-06-28T07:10:37+00:00","releaseTime":"2018-04-19T14:46:35+00:00"},{"id":"18w15a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/104ffb10f7e2017e50525ad6def27d43a1351ffb/18w15a.json","time":"2019-06-28T07:10:35+00:00","releaseTime":"2018-04-11T14:54:22+00:00"},{"id":"18w14b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f1663847c676301b39c6165dfee617b65f633eb3/18w14b.json","time":"2019-06-28T07:10:33+00:00","releaseTime":"2018-04-05T14:44:02+00:00"},{"id":"18w14a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ddb3a3037ebefd9c7921482ce7b71470157b2bae/18w14a.json","time":"2019-06-28T07:10:32+00:00","releaseTime":"2018-04-04T14:36:14+00:00"},{"id":"18w11a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/c508c442a75e5f9bc5645fc6b5d81c95ef9cb9d9/18w11a.json","time":"2019-06-28T07:10:28+00:00","releaseTime":"2018-03-13T15:10:59+00:00"},{"id":"18w10d","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/298dd4f9927310f91e999833ef96211f7e4642db/18w10d.json","time":"2019-06-28T07:10:26+00:00","releaseTime":"2018-03-09T15:19:12+00:00"},{"id":"18w10c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2777b49ae9c7260f4ef39f9afbab6cdc3b0ee703/18w10c.json","time":"2019-06-28T07:10:24+00:00","releaseTime":"2018-03-08T15:29:23+00:00"},{"id":"18w10b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/351e6670bac10aa5ae50017076a01c1f7f6ffec8/18w10b.json","time":"2019-06-28T07:10:22+00:00","releaseTime":"2018-03-07T15:56:01+00:00"},{"id":"18w10a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/9040a647a6496201cf0bc0139664d8eccf153a00/18w10a.json","time":"2019-06-28T07:10:20+00:00","releaseTime":"2018-03-06T15:54:24+00:00"},{"id":"18w09a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2363421af13b87a427a32273f733f628db3bc262/18w09a.json","time":"2019-06-28T07:10:19+00:00","releaseTime":"2018-03-01T14:15:10+00:00"},{"id":"18w08b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/d81bdb924f53a6abb940501c5c1ed03966a2853a/18w08b.json","time":"2019-06-28T07:10:17+00:00","releaseTime":"2018-02-22T15:44:49+00:00"},{"id":"18w08a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/57ebf115603deaa30e1e22bf4e13cd4824bca925/18w08a.json","time":"2019-06-28T07:10:15+00:00","releaseTime":"2018-02-21T14:59:00+00:00"},{"id":"18w07c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/bfa0e12abbeca98ea31931a8ff9e328bb09d017a/18w07c.json","time":"2019-06-28T07:10:13+00:00","releaseTime":"2018-02-16T13:23:32+00:00"},{"id":"18w07b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/24ff49e1f821ccac495af70d7e8779e013251294/18w07b.json","time":"2019-06-28T07:10:11+00:00","releaseTime":"2018-02-15T14:28:42+00:00"},{"id":"18w07a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/45d425c0ceb8e451886f6e90ff116f20a90d17d8/18w07a.json","time":"2019-06-28T07:10:10+00:00","releaseTime":"2018-02-14T17:34:13+00:00"},{"id":"18w06a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/83670eeb3b4579b6f93d4228b7e2bc1f89475d71/18w06a.json","time":"2019-06-28T07:10:08+00:00","releaseTime":"2018-02-09T12:09:55+00:00"},{"id":"18w05a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a9e94f4c88dd7905aa475f04ba3bfc134b70754a/18w05a.json","time":"2019-06-28T07:10:03+00:00","releaseTime":"2018-01-31T13:32:09+00:00"},{"id":"18w03b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ceb0851b72357177d6d817ddda3af082ca80ca3a/18w03b.json","time":"2019-06-28T07:10:00+00:00","releaseTime":"2018-01-17T15:09:14+00:00"},{"id":"18w03a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/fd5fb7fae09fac64397224517ab529e3bbfa3e70/18w03a.json","time":"2019-06-28T07:09:59+00:00","releaseTime":"2018-01-17T14:25:24+00:00"},{"id":"18w02a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b0ddd29e3ab04729b1948bb50d9431cce420724d/18w02a.json","time":"2019-06-28T07:09:57+00:00","releaseTime":"2018-01-10T11:54:55+00:00"},{"id":"18w01a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b1f57752ac2e0ead0fdd7434140bf2f5088cff40/18w01a.json","time":"2019-06-28T07:09:54+00:00","releaseTime":"2018-01-03T13:29:30+00:00"},{"id":"17w50a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/e116ee9be7f2aa00af3c3c6ff7a95991b550b1b6/17w50a.json","time":"2019-06-28T07:09:52+00:00","releaseTime":"2017-12-11T15:28:08+00:00"},{"id":"17w49b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f8d0a2d9bc6b178c941fb31069196574b4858732/17w49b.json","time":"2019-06-28T07:09:49+00:00","releaseTime":"2017-12-07T15:29:54+00:00"},{"id":"17w49a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/6de4e269122102c9cdaa49ce1a65f9b185dcc86b/17w49a.json","time":"2019-06-28T07:09:47+00:00","releaseTime":"2017-12-06T14:24:30+00:00"},{"id":"17w48a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f0cd9d5fef902a57075246580a12413caba68c4b/17w48a.json","time":"2019-06-28T07:09:45+00:00","releaseTime":"2017-11-27T15:36:33+00:00"},{"id":"17w47b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/7081b367c5a7d140cdf58fa6788f403968808b19/17w47b.json","time":"2019-06-28T07:09:43+00:00","releaseTime":"2017-11-23T15:30:12+00:00"},{"id":"17w47a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/602e8ef598d492f707621954685e029434f27ede/17w47a.json","time":"2019-06-28T07:09:41+00:00","releaseTime":"2017-11-22T12:40:05+00:00"},{"id":"17w46a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/5b07e94d1276496e661c99d117b8dc5df4f6d099/17w46a.json","time":"2019-06-28T07:09:39+00:00","releaseTime":"2017-11-15T15:21:55+00:00"},{"id":"17w45b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f9acb09376005f47f647ebb8bc687e5ba9e515ec/17w45b.json","time":"2019-06-28T07:09:37+00:00","releaseTime":"2017-11-10T10:07:02+00:00"},{"id":"17w45a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/c3a0cc0ba68d054095dc52010b7b71a35b9ab17f/17w45a.json","time":"2019-06-28T07:09:35+00:00","releaseTime":"2017-11-08T15:48:00+00:00"},{"id":"17w43b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/5ee9c314fc10b6501711802802818c0d75d6c4e7/17w43b.json","time":"2019-06-28T07:09:32+00:00","releaseTime":"2017-10-26T13:36:22+00:00"},{"id":"17w43a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/e83e27bd416cc5abed43f86e01579fdeb1801ea5/17w43a.json","time":"2019-06-28T07:09:31+00:00","releaseTime":"2017-10-25T14:43:50+00:00"},{"id":"1.12.2","type":"release","url":"https://launchermeta.mojang.com/v1/packages/6e69e85d0f85f4f4b9e12dd99d102092a6e15918/1.12.2.json","time":"2019-06-28T07:05:57+00:00","releaseTime":"2017-09-18T08:39:46+00:00"},{"id":"1.12.2-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b3f6aa5c952b9ff8c39046b3fb7fe3b712a9909a/1.12.2-pre2.json","time":"2019-06-28T07:06:46+00:00","releaseTime":"2017-09-15T08:21:17+00:00"},{"id":"1.12.2-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ce18ba69f4d0a7947d182b47d7a3bd499d24a1e2/1.12.2-pre1.json","time":"2019-06-28T07:06:44+00:00","releaseTime":"2017-09-13T13:33:31+00:00"},{"id":"1.12.1","type":"release","url":"https://launchermeta.mojang.com/v1/packages/24b28f562e354309697a1c9d835dea55a185df1e/1.12.1.json","time":"2019-06-28T07:05:56+00:00","releaseTime":"2017-08-03T12:40:39+00:00"},{"id":"1.12.1-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/fb7202af7c5d5efd6f81e5db6aa8de04e049bc08/1.12.1-pre1.json","time":"2019-06-28T07:06:43+00:00","releaseTime":"2017-08-02T10:53:55+00:00"},{"id":"17w31a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ed63bb5facba58bfeed785149e05dd33910135fc/17w31a.json","time":"2019-06-28T07:09:29+00:00","releaseTime":"2017-08-01T09:41:23+00:00"},{"id":"1.12","type":"release","url":"https://launchermeta.mojang.com/v1/packages/367843437acbae63de3084dd6afd3dd8bd2a7479/1.12.json","time":"2019-06-28T07:05:59+00:00","releaseTime":"2017-06-02T13:50:27+00:00"},{"id":"1.12-pre7","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/d734d4070653b2c0e8e6a5abed905d78982203f7/1.12-pre7.json","time":"2019-06-28T07:06:42+00:00","releaseTime":"2017-05-31T10:56:41+00:00"},{"id":"1.12-pre6","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/3fa2c3b5ff806ce0acbffd8db0895525ed253e32/1.12-pre6.json","time":"2019-06-28T07:06:40+00:00","releaseTime":"2017-05-29T11:45:12+00:00"},{"id":"1.12-pre5","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2069bb4938682be97f248baa73d970d37b61d540/1.12-pre5.json","time":"2019-06-28T07:06:38+00:00","releaseTime":"2017-05-19T07:43:28+00:00"},{"id":"1.12-pre4","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/9fc87076b48db5717efe92183a44049b90eae915/1.12-pre4.json","time":"2019-06-28T07:06:37+00:00","releaseTime":"2017-05-18T12:28:16+00:00"},{"id":"1.12-pre3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a2dc7f1792b986f3b1456630e0a76b9cfb37acc6/1.12-pre3.json","time":"2019-06-28T07:06:35+00:00","releaseTime":"2017-05-17T14:09:18+00:00"},{"id":"1.12-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a472bb7234be82c489f5c7fca03724298a95585b/1.12-pre2.json","time":"2019-06-28T07:06:33+00:00","releaseTime":"2017-05-11T12:11:12+00:00"},{"id":"1.12-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/51695897d818f3414ce5dbea33dea58682c6dc44/1.12-pre1.json","time":"2019-06-28T07:06:32+00:00","releaseTime":"2017-05-10T11:37:17+00:00"},{"id":"17w18b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/03c7dbe028a8a62862d4fec5951343ff0f5012b5/17w18b.json","time":"2019-06-28T07:09:27+00:00","releaseTime":"2017-05-04T13:40:22+00:00"},{"id":"17w18a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/03ca07f26b8336732e720ecd13e912e19f0d3a77/17w18a.json","time":"2019-06-28T07:09:26+00:00","releaseTime":"2017-05-03T14:50:23+00:00"},{"id":"17w17b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f8751aa4fcb4f2aa0955c3fae1d4cd9a12c89979/17w17b.json","time":"2019-06-28T07:09:24+00:00","releaseTime":"2017-04-27T13:24:23+00:00"},{"id":"17w17a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b2ffee6fc34b1f2cba708c544492ea939d6773fc/17w17a.json","time":"2019-06-28T07:09:22+00:00","releaseTime":"2017-04-26T13:48:23+00:00"},{"id":"17w16b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/635a0c0f77e2bf6157c41e25647dfe65cc1b18f4/17w16b.json","time":"2019-06-28T07:09:21+00:00","releaseTime":"2017-04-21T12:02:59+00:00"},{"id":"17w16a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/4baeef9effd9d3eacdb6bef1a974f20be394278b/17w16a.json","time":"2019-06-28T07:09:19+00:00","releaseTime":"2017-04-20T13:58:35+00:00"},{"id":"17w15a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b629aee8a9e4bb4711ee5583aa512d4eaaf73e2e/17w15a.json","time":"2019-06-28T07:09:17+00:00","releaseTime":"2017-04-12T09:30:50+00:00"},{"id":"17w14a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/51f1acd9b0e5f8dff45dc80b4d73eb8e8317e733/17w14a.json","time":"2019-06-28T07:09:15+00:00","releaseTime":"2017-04-05T13:58:01+00:00"},{"id":"17w13b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/4b1a19a71cd90167e7464da777fc6d4bd93c8f6c/17w13b.json","time":"2019-06-28T07:09:14+00:00","releaseTime":"2017-03-31T11:06:35+00:00"},{"id":"17w13a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ec0d9ff2917f223b24725b259d7aea1249f4a07c/17w13a.json","time":"2019-06-28T07:09:12+00:00","releaseTime":"2017-03-30T09:32:19+00:00"},{"id":"17w06a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/17070716831f1f55a42c2f218fd5d7f56c3407fc/17w06a.json","time":"2019-06-28T07:09:10+00:00","releaseTime":"2017-02-08T13:16:29+00:00"},{"id":"1.11.2","type":"release","url":"https://launchermeta.mojang.com/v1/packages/6bd228727ed48bd7ac7bdc0088587dad0fb7c02b/1.11.2.json","time":"2019-06-28T07:05:53+00:00","releaseTime":"2016-12-21T09:29:12+00:00"},{"id":"1.11.1","type":"release","url":"https://launchermeta.mojang.com/v1/packages/363096f6590653e170bcfd56c085c6a77578ba42/1.11.1.json","time":"2019-06-28T07:05:52+00:00","releaseTime":"2016-12-20T14:05:34+00:00"},{"id":"16w50a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/34b08beba7d9711dff07484e17daf9cd9681c770/16w50a.json","time":"2019-06-28T07:09:08+00:00","releaseTime":"2016-12-15T14:38:52+00:00"},{"id":"1.11","type":"release","url":"https://launchermeta.mojang.com/v1/packages/340d2e0f200af20b1e4d5da501facc7fc1cfb0e5/1.11.json","time":"2019-06-28T07:05:55+00:00","releaseTime":"2016-11-14T14:34:40+00:00"},{"id":"1.11-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/fde7baf263756f1bfc20ba51a5b9bc6333b23bd0/1.11-pre1.json","time":"2019-06-28T07:06:30+00:00","releaseTime":"2016-11-08T13:42:50+00:00"},{"id":"16w44a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/85cdd8a8918be3975d4edb1176cfa9971fd2681d/16w44a.json","time":"2019-06-28T07:09:06+00:00","releaseTime":"2016-11-03T14:17:11+00:00"},{"id":"16w43a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/5ddba06d364f30cc871465a25f7325e520a0e544/16w43a.json","time":"2019-06-28T07:09:04+00:00","releaseTime":"2016-10-27T09:00:51+00:00"},{"id":"16w42a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/6ffff59eb02a4fef3c6aee893136858606832183/16w42a.json","time":"2019-06-28T07:09:03+00:00","releaseTime":"2016-10-19T11:17:47+00:00"},{"id":"16w41a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/7d4ece5f41496402d25258e5725b88cb6190284c/16w41a.json","time":"2019-06-28T07:09:01+00:00","releaseTime":"2016-10-13T14:28:35+00:00"},{"id":"16w40a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/53c8af9aa235a12b623fc6be9e02c4aafc1df3ad/16w40a.json","time":"2019-06-28T07:08:59+00:00","releaseTime":"2016-10-06T13:57:59+00:00"},{"id":"16w39c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/e811be4a812aa532b0bbab31d4b22b3b9f7dee70/16w39c.json","time":"2019-06-28T07:08:58+00:00","releaseTime":"2016-09-30T14:11:48+00:00"},{"id":"16w39b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/6ee9f1afbc2fdf74e5c07cfb7298cb84755c6cfd/16w39b.json","time":"2019-06-28T07:08:56+00:00","releaseTime":"2016-09-29T14:39:39+00:00"},{"id":"16w39a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/bac2bd719657ff8524cf97b1913e5a56bb150ac8/16w39a.json","time":"2019-06-28T07:08:54+00:00","releaseTime":"2016-09-28T13:32:06+00:00"},{"id":"16w38a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/fbd5d83a14b4d6e8f7029d3c08dd6985d09c4f40/16w38a.json","time":"2019-06-28T07:08:53+00:00","releaseTime":"2016-09-20T12:40:49+00:00"},{"id":"16w36a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/9d775a6488e53e42267585dd5924178c3f601d7d/16w36a.json","time":"2019-06-28T07:08:51+00:00","releaseTime":"2016-09-08T14:55:10+00:00"},{"id":"16w35a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/e64f1a32444286fc5fcd65dca20709ce5963d066/16w35a.json","time":"2019-06-28T07:08:49+00:00","releaseTime":"2016-09-01T13:13:38+00:00"},{"id":"16w33a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/3065c85819ff5854f991c5e4bfde2b6d8832d981/16w33a.json","time":"2019-06-28T07:08:48+00:00","releaseTime":"2016-08-17T12:48:57+00:00"},{"id":"16w32b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a672dd946075b43da267bcd73d3953f09845767c/16w32b.json","time":"2019-06-28T07:08:46+00:00","releaseTime":"2016-08-11T14:34:29+00:00"},{"id":"16w32a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/78178d605ec7bb141b91b4eed36adb9ffdf82527/16w32a.json","time":"2019-06-28T07:08:44+00:00","releaseTime":"2016-08-10T12:30:10+00:00"},{"id":"1.10.2","type":"release","url":"https://launchermeta.mojang.com/v1/packages/9e23991d61e9b4eb9dfee56cb8ee7392fb925aff/1.10.2.json","time":"2019-06-28T07:05:49+00:00","releaseTime":"2016-06-23T09:17:32+00:00"},{"id":"1.10.1","type":"release","url":"https://launchermeta.mojang.com/v1/packages/ee31c565a9aa614676b786c55a0be77268743b60/1.10.1.json","time":"2019-06-28T07:05:48+00:00","releaseTime":"2016-06-22T10:13:22+00:00"},{"id":"1.10","type":"release","url":"https://launchermeta.mojang.com/v1/packages/0590cc1c11f1be246af9d972f919693bf6b0d1f6/1.10.json","time":"2019-06-28T07:05:51+00:00","releaseTime":"2016-06-08T13:06:18+00:00"},{"id":"1.10-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/bd196d2494f334adcefd78089b0d371a22bee56b/1.10-pre2.json","time":"2019-06-28T07:06:28+00:00","releaseTime":"2016-06-07T14:56:34+00:00"},{"id":"1.10-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/08a9c29b2cd4df7c9ad51ab0be5f9683c20d4c3f/1.10-pre1.json","time":"2019-06-28T07:06:27+00:00","releaseTime":"2016-06-02T14:45:16+00:00"},{"id":"16w21b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/c9e280d280279b0cb1b4906d33fdab47524dd719/16w21b.json","time":"2019-06-28T07:08:43+00:00","releaseTime":"2016-05-26T12:47:22+00:00"},{"id":"16w21a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ccdf81a69335bc84fae0ae69663ae82f9e277a0d/16w21a.json","time":"2019-06-28T07:08:41+00:00","releaseTime":"2016-05-25T13:12:09+00:00"},{"id":"16w20a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a1958213b24176f0cd6698929ae965caec5eb53f/16w20a.json","time":"2019-06-28T07:08:40+00:00","releaseTime":"2016-05-18T12:45:14+00:00"},{"id":"1.9.4","type":"release","url":"https://launchermeta.mojang.com/v1/packages/7f40b382dedcfe9eca74a5b14d615075ec34c108/1.9.4.json","time":"2019-06-28T07:06:24+00:00","releaseTime":"2016-05-10T10:17:16+00:00"},{"id":"1.9.3","type":"release","url":"https://launchermeta.mojang.com/v1/packages/e8bab05ecee645e3c9b962f532ca7fd6c52e120e/1.9.3.json","time":"2019-06-28T07:06:23+00:00","releaseTime":"2016-05-10T08:33:35+00:00"},{"id":"1.9.3-pre3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/84e5b1bf3974e0ef38f9badce9db14d68419a57e/1.9.3-pre3.json","time":"2019-06-28T07:08:04+00:00","releaseTime":"2016-05-03T09:28:11+00:00"},{"id":"1.9.3-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/e1a60758446450cd5631d5191216b00b1e87a633/1.9.3-pre2.json","time":"2019-06-28T07:08:03+00:00","releaseTime":"2016-04-27T13:33:20+00:00"},{"id":"1.9.3-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/9f5e4882ac87d6e479f60e62705f0b6bd3f96d47/1.9.3-pre1.json","time":"2019-06-28T07:08:01+00:00","releaseTime":"2016-04-21T12:41:42+00:00"},{"id":"16w15b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/eb2ded7b829a5938af1f83587c4c63d27a953024/16w15b.json","time":"2019-06-28T07:08:38+00:00","releaseTime":"2016-04-13T13:56:41+00:00"},{"id":"16w15a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/93791968f6648db8039e972d13dfc405b1516f8d/16w15a.json","time":"2019-06-28T07:08:37+00:00","releaseTime":"2016-04-11T14:38:28+00:00"},{"id":"16w14a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/c62d4d7fd9df479b0f5084e2c833a22474b25c23/16w14a.json","time":"2019-06-28T07:08:35+00:00","releaseTime":"2016-04-07T12:47:51+00:00"},{"id":"1.RV-Pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/3c1973d91e234fa30eb12be0dce7587b0b3c75bd/1.RV-Pre1.json","time":"2019-06-28T07:08:06+00:00","releaseTime":"2016-03-31T16:18:53+00:00"},{"id":"1.9.2","type":"release","url":"https://launchermeta.mojang.com/v1/packages/3cc8cee91366290508c8767e8826c6352c2b89c5/1.9.2.json","time":"2019-06-28T07:06:22+00:00","releaseTime":"2016-03-30T15:23:55+00:00"},{"id":"1.9.1","type":"release","url":"https://launchermeta.mojang.com/v1/packages/a7c5c055718d8e7d709f3f2338b4e8f1125b5aae/1.9.1.json","time":"2019-06-28T07:06:20+00:00","releaseTime":"2016-03-30T13:43:07+00:00"},{"id":"1.9.1-pre3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2c5e8a1d144de3c9b2e3c543675313ac821d967b/1.9.1-pre3.json","time":"2019-06-28T07:08:00+00:00","releaseTime":"2016-03-11T09:20:36+00:00"},{"id":"1.9.1-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/cb1f20ffabf06b466406a93041ce10c4f7d7b1de/1.9.1-pre2.json","time":"2019-06-28T07:07:58+00:00","releaseTime":"2016-03-10T15:06:03+00:00"},{"id":"1.9.1-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/440cb683d6c525e5c2201e2be89d75451c30c426/1.9.1-pre1.json","time":"2019-06-28T07:07:57+00:00","releaseTime":"2016-03-09T16:27:29+00:00"},{"id":"1.9","type":"release","url":"https://launchermeta.mojang.com/v1/packages/fab85b386a3de3009e5944b0183ce063faa09691/1.9.json","time":"2019-06-28T07:06:25+00:00","releaseTime":"2016-02-29T13:49:54+00:00"},{"id":"1.9-pre4","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/6a64da9184804a50d0b3fd9d71725c5e38862f8d/1.9-pre4.json","time":"2019-06-28T07:07:56+00:00","releaseTime":"2016-02-26T15:21:11+00:00"},{"id":"1.9-pre3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2afcc13afbad403ade52d562b5737dc7c40d357f/1.9-pre3.json","time":"2019-06-28T07:07:55+00:00","releaseTime":"2016-02-24T15:52:36+00:00"},{"id":"1.9-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/479af80b2ad5442eedf5bfb3b1b16cb219ba0a1f/1.9-pre2.json","time":"2019-06-28T07:07:53+00:00","releaseTime":"2016-02-18T17:41:00+00:00"},{"id":"1.9-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/7c1e51a0fd773629192004941858d7e39b130166/1.9-pre1.json","time":"2019-06-28T07:07:52+00:00","releaseTime":"2016-02-17T15:23:19+00:00"},{"id":"16w07b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/7a90eb9033a0174be4133da67a3bb8ff4520467c/16w07b.json","time":"2019-06-28T07:08:34+00:00","releaseTime":"2016-02-16T15:22:39+00:00"},{"id":"16w07a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/002431778380004494d981d4449e9d02f9ed73de/16w07a.json","time":"2019-06-28T07:08:32+00:00","releaseTime":"2016-02-15T15:48:46+00:00"},{"id":"16w06a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f90799db6ea46ee93a3abade178475864c30427b/16w06a.json","time":"2019-06-28T07:08:31+00:00","releaseTime":"2016-02-10T15:06:41+00:00"},{"id":"16w05b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f2d853e1e3d55de9f220e923eee762de5ff4cf42/16w05b.json","time":"2019-06-28T07:08:29+00:00","releaseTime":"2016-02-04T15:28:02+00:00"},{"id":"16w05a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/119bce41454a1d3ade4fbab1894540cff4ed1380/16w05a.json","time":"2019-06-28T07:08:27+00:00","releaseTime":"2016-02-03T15:48:38+00:00"},{"id":"16w04a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/dbe7c4755088d3cea55c40b207915e601ed573dc/16w04a.json","time":"2019-06-28T09:31:11+00:00","releaseTime":"2016-01-28T15:37:24+00:00"},{"id":"16w03a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/0c68af2406f0ee25b93305e28dcb3978275a23ca/16w03a.json","time":"2019-06-28T09:31:10+00:00","releaseTime":"2016-01-20T14:29:24+00:00"},{"id":"16w02a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2f6007d145fb6dc0406bedc21e1d5345c84cd5d7/16w02a.json","time":"2019-06-28T09:31:09+00:00","releaseTime":"2016-01-13T15:15:16+00:00"},{"id":"15w51b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/3fe2e181cbe3daa24a3f824a547fa241268686b2/15w51b.json","time":"2019-06-28T09:31:05+00:00","releaseTime":"2015-12-17T15:30:41+00:00"},{"id":"15w51a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/7070c87a526910524cbec04c3e0b76759a0208f3/15w51a.json","time":"2019-06-28T09:31:04+00:00","releaseTime":"2015-12-17T14:02:37+00:00"},{"id":"15w50a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/89807df9342360d793089116e8c226223059c4c1/15w50a.json","time":"2019-06-28T09:31:02+00:00","releaseTime":"2015-12-09T15:35:57+00:00"},{"id":"15w49b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/7b707a788fbee737fdf209b03af308c940a38ba6/15w49b.json","time":"2019-06-28T09:31:01+00:00","releaseTime":"2015-12-03T15:23:22+00:00"},{"id":"1.8.9","type":"release","url":"https://launchermeta.mojang.com/v1/packages/856d9bec08b0d567de39f46efaf4b76066b53059/1.8.9.json","time":"2019-06-28T09:30:03+00:00","releaseTime":"2015-12-03T09:24:39+00:00"},{"id":"15w49a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/4ccaa5b6ce63f7863d8535e85069581c0f04c3ab/15w49a.json","time":"2019-06-28T09:31:00+00:00","releaseTime":"2015-12-02T15:09:37+00:00"},{"id":"15w47c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/9d3d456943c1c9c0dd3662e3f99dea1ce0bbeb57/15w47c.json","time":"2019-06-28T09:30:58+00:00","releaseTime":"2015-11-20T12:46:56+00:00"},{"id":"15w47b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/c52201eca7acd017743fb9b9a66700c729c8fe78/15w47b.json","time":"2019-06-28T09:30:57+00:00","releaseTime":"2015-11-19T14:48:03+00:00"},{"id":"15w47a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/704b41ca962e73deeaea78d3c6fc07f01e7f02c8/15w47a.json","time":"2019-06-28T09:30:53+00:00","releaseTime":"2015-11-18T15:53:41+00:00"},{"id":"15w46a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ed28a3f252a40cd4dfa3a84f9c7a1aab5f79493b/15w46a.json","time":"2019-06-28T09:30:52+00:00","releaseTime":"2015-11-12T12:11:47+00:00"},{"id":"15w45a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/15829ef167c98687ca0c4c7d140225efe2769bed/15w45a.json","time":"2019-06-28T09:30:51+00:00","releaseTime":"2015-11-05T13:04:07+00:00"},{"id":"15w44b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a2d3fd6e371e1a789f432227328f6967c5b6bc7e/15w44b.json","time":"2019-06-28T09:30:50+00:00","releaseTime":"2015-10-30T11:23:17+00:00"},{"id":"15w44a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/57a72f59f661a1b00d6c152f3663fc4af35714ed/15w44a.json","time":"2019-06-28T09:30:48+00:00","releaseTime":"2015-10-28T15:09:36+00:00"},{"id":"15w43c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/57b03175602261e9f2787cd513e05fe6ee0c8b6d/15w43c.json","time":"2019-06-28T09:30:47+00:00","releaseTime":"2015-10-23T15:35:55+00:00"},{"id":"15w43b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/cf68e682555c704dec3796db1b2ae7f6f84b31ed/15w43b.json","time":"2019-06-28T09:30:46+00:00","releaseTime":"2015-10-22T14:11:58+00:00"},{"id":"15w43a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/06fddff71f0c2590cbee9b179b076e4c2516c72a/15w43a.json","time":"2019-06-28T09:30:45+00:00","releaseTime":"2015-10-21T15:28:52+00:00"},{"id":"15w42a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/544aa5c98d30017dd12769feed0f6ac411cb120e/15w42a.json","time":"2019-06-28T09:30:43+00:00","releaseTime":"2015-10-14T13:25:14+00:00"},{"id":"15w41b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/1e77da8ae623253dceb946a831499821b9ff3469/15w41b.json","time":"2019-06-28T09:30:42+00:00","releaseTime":"2015-10-07T14:07:26+00:00"},{"id":"15w41a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/1667759ebf20581022f06b926976f8a0906950b4/15w41a.json","time":"2019-06-28T09:30:41+00:00","releaseTime":"2015-10-07T13:19:53+00:00"},{"id":"15w40b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/722edb06697f9552919310222e6e384885a122d2/15w40b.json","time":"2019-06-28T09:30:40+00:00","releaseTime":"2015-09-30T14:13:54+00:00"},{"id":"15w40a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/979332ff22b5883583db3427feb76da226d9c510/15w40a.json","time":"2019-06-28T09:30:38+00:00","releaseTime":"2015-09-30T13:13:54+00:00"},{"id":"15w39c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/9c6872f8758ca25a5c7d4378700d2cbf7b9e88f7/15w39c.json","time":"2019-06-28T09:30:37+00:00","releaseTime":"2015-09-23T13:13:54+00:00"},{"id":"15w39b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/5a78fbe82c699c64438d34fbb1fecdff07a20e74/15w39b.json","time":"2019-06-28T07:08:20+00:00","releaseTime":"2015-09-21T15:09:52+00:00"},{"id":"15w39a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/75423b4d58f4247fba33e71822b970e5c2c0d841/15w39a.json","time":"2019-06-28T07:08:20+00:00","releaseTime":"2015-09-21T13:16:32+00:00"},{"id":"15w38b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/5324ca4063759d9d44557d8514db4ff36823ea68/15w38b.json","time":"2019-06-28T09:30:36+00:00","releaseTime":"2015-09-17T14:22:31+00:00"},{"id":"15w38a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f6ca23e9ea8a6ba939eba48c9c38bbffdb3c2bd8/15w38a.json","time":"2019-06-28T09:30:35+00:00","releaseTime":"2015-09-16T14:22:31+00:00"},{"id":"15w37a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/e94380c8f89d89e5ec3ef0a087af5907c67a3a97/15w37a.json","time":"2019-06-28T09:30:34+00:00","releaseTime":"2015-09-10T14:22:31+00:00"},{"id":"15w36d","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/70730c79f021c92eea9c099f1cabb908ce7a2016/15w36d.json","time":"2019-06-28T09:30:32+00:00","releaseTime":"2015-09-04T14:22:31+00:00"},{"id":"15w36c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/8ab2e79205adf5e84857eec0ccc9e24612f34db2/15w36c.json","time":"2019-06-28T09:30:31+00:00","releaseTime":"2015-09-02T16:07:22+00:00"},{"id":"15w36b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/834c0125a54c72543a5956f8f84a132983c51a01/15w36b.json","time":"2019-06-28T09:30:30+00:00","releaseTime":"2015-09-02T15:36:25+00:00"},{"id":"15w36a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/851de2edecdd714d0deaeb6138a8aca5da02575f/15w36a.json","time":"2019-06-28T09:30:29+00:00","releaseTime":"2015-09-02T14:46:40+00:00"},{"id":"15w35e","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/e5fde3e58e56bd04ddda7bee585d7034a3a0e43f/15w35e.json","time":"2019-06-28T09:30:28+00:00","releaseTime":"2015-08-28T18:14:02+00:00"},{"id":"15w35d","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/408cbdd6dba59c8826ac7e960461f62bf89e0f93/15w35d.json","time":"2019-06-28T09:30:27+00:00","releaseTime":"2015-08-28T16:25:35+00:00"},{"id":"15w35c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/8ae6715d0a632afaf4322125887a935d2414b2c3/15w35c.json","time":"2019-06-28T09:30:25+00:00","releaseTime":"2015-08-28T11:21:00+00:00"},{"id":"15w35b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/7f4f70d63fb85b02aa6512382c7815923ad0151f/15w35b.json","time":"2019-06-28T09:30:24+00:00","releaseTime":"2015-08-24T15:39:18+00:00"},{"id":"15w35a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/4ab25b24d191d46add8c53bb8714c5fd113bd2e6/15w35a.json","time":"2019-06-28T09:30:23+00:00","releaseTime":"2015-08-24T14:19:31+00:00"},{"id":"15w34d","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/eb6f497f5c40fe804fe859b62edae4f8a0b18cb8/15w34d.json","time":"2019-06-28T09:30:22+00:00","releaseTime":"2015-08-21T15:27:55+00:00"},{"id":"15w34c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/85b06fb6e7527063bf76adc7bad1f2644affc166/15w34c.json","time":"2019-06-28T09:30:21+00:00","releaseTime":"2015-08-21T12:45:20+00:00"},{"id":"15w34b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/08021851a9711f2665d7dce0fe0cbf7528bf482d/15w34b.json","time":"2019-06-28T09:30:19+00:00","releaseTime":"2015-08-20T14:00:03+00:00"},{"id":"15w34a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/71b1b3cc02415227a5600d97c84eb211b741a49f/15w34a.json","time":"2019-06-28T09:30:18+00:00","releaseTime":"2015-08-19T12:56:01+00:00"},{"id":"15w33c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2b27de469db8b259764d97fb7570f668a1cc7606/15w33c.json","time":"2019-06-28T09:30:17+00:00","releaseTime":"2015-08-14T13:10:46+00:00"},{"id":"15w33b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a06b1d00ba90e10c3aa83bdfd9469cefffde8ba7/15w33b.json","time":"2019-06-28T09:30:16+00:00","releaseTime":"2015-08-12T15:29:11+00:00"},{"id":"15w33a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a31c9b43de60bdc2410d63716f522b2242843b38/15w33a.json","time":"2019-06-28T07:08:18+00:00","releaseTime":"2015-08-12T14:05:07+00:00"},{"id":"15w32c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/79372029c5f7164c4106b3445c6a72fd89b91641/15w32c.json","time":"2019-06-28T09:30:15+00:00","releaseTime":"2015-08-07T14:08:17+00:00"},{"id":"15w32b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/7b39a2921fd7f29cc0cead1045adc1d08f55d7fb/15w32b.json","time":"2019-06-28T09:30:14+00:00","releaseTime":"2015-08-06T13:51:47+00:00"},{"id":"15w32a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/c04d45676b3c64735e07f485207530359fd208f2/15w32a.json","time":"2019-06-28T09:30:12+00:00","releaseTime":"2015-08-05T12:22:42+00:00"},{"id":"15w31c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/c617cf4d2350d0936b0cd532e204d4c0db9a8695/15w31c.json","time":"2019-06-28T09:30:11+00:00","releaseTime":"2015-07-31T13:45:08+00:00"},{"id":"15w31b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/705e90b4e738b47cf768926cd1f54ed56e6562d2/15w31b.json","time":"2019-06-28T09:30:10+00:00","releaseTime":"2015-07-30T13:38:32+00:00"},{"id":"15w31a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/bd5a158581e6ceec4c34b32774153661b63913e3/15w31a.json","time":"2019-06-28T09:30:08+00:00","releaseTime":"2015-07-29T13:24:33+00:00"},{"id":"1.8.8","type":"release","url":"https://launchermeta.mojang.com/v1/packages/389ee2576f1c7ac6efe0edcec79f2e465d2a5278/1.8.8.json","time":"2019-06-28T09:30:02+00:00","releaseTime":"2015-07-27T10:31:28+00:00"},{"id":"1.8.7","type":"release","url":"https://launchermeta.mojang.com/v1/packages/87c78678d155ff55fc91fc64a7a84f2daf855f1e/1.8.7.json","time":"2019-06-28T09:30:00+00:00","releaseTime":"2015-06-05T10:10:44+00:00"},{"id":"1.8.6","type":"release","url":"https://launchermeta.mojang.com/v1/packages/13b52ffde81121125d69aec94589abfba7e04147/1.8.6.json","time":"2019-06-28T09:29:59+00:00","releaseTime":"2015-05-25T10:31:19+00:00"},{"id":"1.8.5","type":"release","url":"https://launchermeta.mojang.com/v1/packages/ced2d59fde6e68ca9e84bbb00e5c7dc9c052df06/1.8.5.json","time":"2019-06-28T09:29:58+00:00","releaseTime":"2015-05-22T11:15:28+00:00"},{"id":"1.8.4","type":"release","url":"https://launchermeta.mojang.com/v1/packages/bf6b4b4bef435804faacc6fb8d350119a7482262/1.8.4.json","time":"2019-06-28T09:29:57+00:00","releaseTime":"2015-04-17T11:37:50+00:00"},{"id":"15w14a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/18fff5c4aaa556b97a66d6651cbf6a3484ac97e4/15w14a.json","time":"2019-06-28T07:08:17+00:00","releaseTime":"2015-04-01T07:08:00+00:00"},{"id":"1.8.3","type":"release","url":"https://launchermeta.mojang.com/v1/packages/94f0e372077d0fe6cfeaad990b2c25ba67b3531c/1.8.3.json","time":"2019-06-28T09:29:56+00:00","releaseTime":"2015-02-20T14:00:09+00:00"},{"id":"1.8.2","type":"release","url":"https://launchermeta.mojang.com/v1/packages/05655de45c43872c48eea1e07ae9740bc4cdf47e/1.8.2.json","time":"2019-06-28T09:29:54+00:00","releaseTime":"2015-02-19T15:47:29+00:00"},{"id":"1.8.2-pre7","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/15e11b9224f6eebee835685523ce209cf16bf7e8/1.8.2-pre7.json","time":"2019-06-28T07:07:50+00:00","releaseTime":"2015-02-16T13:01:35+00:00"},{"id":"1.8.2-pre6","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f8568849a5cf9aae4693f72704ca43e438057b85/1.8.2-pre6.json","time":"2019-06-28T07:07:50+00:00","releaseTime":"2015-01-30T11:58:24+00:00"},{"id":"1.8.2-pre5","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f507249b1e38774fe1acb4f923190a4466fd7200/1.8.2-pre5.json","time":"2019-06-28T07:07:50+00:00","releaseTime":"2015-01-26T15:03:24+00:00"},{"id":"1.8.2-pre4","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/cbad80725e00af8857ddfbf15bd160099b630e07/1.8.2-pre4.json","time":"2019-06-28T07:07:50+00:00","releaseTime":"2015-01-16T14:19:59+00:00"},{"id":"1.8.2-pre3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/6c40eb3030a4c327c03d0ac50b13199cfef69051/1.8.2-pre3.json","time":"2019-06-28T07:07:50+00:00","releaseTime":"2015-01-15T16:44:33+00:00"},{"id":"1.8.2-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/544bba3b67c7b08a3445432b7071393b9c8ed86a/1.8.2-pre2.json","time":"2019-06-28T07:07:49+00:00","releaseTime":"2015-01-15T15:07:31+00:00"},{"id":"1.8.2-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ac9ed8bd2a93295eb15caba10af6b92e6cec2eb7/1.8.2-pre1.json","time":"2019-06-28T07:07:49+00:00","releaseTime":"2014-12-18T11:29:41+00:00"},{"id":"1.8.1","type":"release","url":"https://launchermeta.mojang.com/v1/packages/cc3bf2b602bcb4d55b4581ea9bb55c4e4b2d9bc9/1.8.1.json","time":"2019-06-28T09:29:53+00:00","releaseTime":"2014-11-24T14:13:31+00:00"},{"id":"1.8.1-pre5","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/6988d729f5e1013395e6d04c903d2b224491da21/1.8.1-pre5.json","time":"2019-06-28T07:07:49+00:00","releaseTime":"2014-11-19T14:30:48+00:00"},{"id":"1.8.1-pre4","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/384982851d1ba287a6e8f57a23d980bc21989101/1.8.1-pre4.json","time":"2019-06-28T07:07:49+00:00","releaseTime":"2014-11-06T14:10:50+00:00"},{"id":"1.8.1-pre3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a2f10c2bb65925c9fccf2395608dcc3b393e76a7/1.8.1-pre3.json","time":"2019-06-28T07:07:49+00:00","releaseTime":"2014-10-23T12:59:42+00:00"},{"id":"1.8.1-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/5799aa67b9a0e18abb9c9705babfd291a43c0b07/1.8.1-pre2.json","time":"2019-06-28T07:07:49+00:00","releaseTime":"2014-10-16T14:19:27+00:00"},{"id":"1.8.1-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/8689f4a30cec09a4339f06a4c8100b81d407cad2/1.8.1-pre1.json","time":"2019-06-28T07:07:49+00:00","releaseTime":"2014-10-15T13:25:11+00:00"},{"id":"1.8","type":"release","url":"https://launchermeta.mojang.com/v1/packages/c6309181ce8df8a06ed556e315cd4636c4082b9a/1.8.json","time":"2019-06-28T09:30:05+00:00","releaseTime":"2014-09-02T08:24:35+00:00"},{"id":"1.8-pre3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/3b5e366a0f265c4dce1354ba76e1a53dae1f1c1a/1.8-pre3.json","time":"2019-06-28T07:07:49+00:00","releaseTime":"2014-08-28T09:40:54+00:00"},{"id":"1.8-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/8a41c8e0f33834284ecc64c042dfe03a5ad5998d/1.8-pre2.json","time":"2019-06-28T07:07:48+00:00","releaseTime":"2014-08-25T14:52:18+00:00"},{"id":"1.8-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b33940927ffd7f5112af8e90a8e726a57a542ccb/1.8-pre1.json","time":"2019-06-28T07:07:48+00:00","releaseTime":"2014-08-21T13:56:26+00:00"},{"id":"14w34d","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2a8b971cbe57230242c7a6f7f9da8796f95400d4/14w34d.json","time":"2019-06-28T07:08:17+00:00","releaseTime":"2014-08-20T12:46:59+00:00"},{"id":"14w34c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/73382e160ea059e990f6af8dc068c155506e0bad/14w34c.json","time":"2019-06-28T07:08:17+00:00","releaseTime":"2014-08-19T15:31:24+00:00"},{"id":"14w34b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/9d27f8e4593e28316ea458bf66cf666bc78d44b3/14w34b.json","time":"2019-06-28T07:08:16+00:00","releaseTime":"2014-08-18T15:14:28+00:00"},{"id":"14w34a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/91086b10591fc00bd66b9eb62b49d40a6ef19e4b/14w34a.json","time":"2019-06-28T07:08:16+00:00","releaseTime":"2014-08-18T14:14:11+00:00"},{"id":"14w33c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f578b2cfcc8c7e03f185f51135c533e780f7fee0/14w33c.json","time":"2019-06-28T07:08:16+00:00","releaseTime":"2014-08-15T18:00:26+00:00"},{"id":"14w33b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/cc33663d42af1a69adc7fa934b34e11cafabaac4/14w33b.json","time":"2019-06-28T07:08:16+00:00","releaseTime":"2014-08-15T16:23:51+00:00"},{"id":"14w33a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/d428ae184b2362dbd4a822a6955f98162040c523/14w33a.json","time":"2019-06-28T07:08:16+00:00","releaseTime":"2014-08-13T15:08:14+00:00"},{"id":"14w32d","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/8d49aa8007af2738aa0d14ce4f248622f4cc2ebe/14w32d.json","time":"2019-06-28T07:08:16+00:00","releaseTime":"2014-08-08T15:13:41+00:00"},{"id":"14w32c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/28096d1beba37533f16bc08ad80f9a5ccceca791/14w32c.json","time":"2019-06-28T07:08:16+00:00","releaseTime":"2014-08-08T14:11:20+00:00"},{"id":"14w32b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/9010ff6f3dc5e1fce9dc071438a24baeb93491d6/14w32b.json","time":"2019-06-28T07:08:15+00:00","releaseTime":"2014-08-07T14:45:17+00:00"},{"id":"14w32a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/d64a982daf815491ef04cdf8a38b1c915da83ba1/14w32a.json","time":"2019-06-28T07:08:15+00:00","releaseTime":"2014-08-06T14:01:16+00:00"},{"id":"14w31a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ef279ffa71f8f36481dad0de9744e166805d54fc/14w31a.json","time":"2019-06-28T07:08:15+00:00","releaseTime":"2014-07-30T15:38:05+00:00"},{"id":"14w30c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/76b580097ce6f4481828425518a139cf3cedee35/14w30c.json","time":"2019-06-28T07:08:15+00:00","releaseTime":"2014-07-24T14:39:09+00:00"},{"id":"14w30b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/8d57bc2e01916ff6fce4f370ae1cbee639a76428/14w30b.json","time":"2019-06-28T07:08:15+00:00","releaseTime":"2014-07-23T15:03:03+00:00"},{"id":"14w30a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/8d57966d0f23a9f97af540709f1b51bd8d02b21d/14w30a.json","time":"2019-06-28T07:08:15+00:00","releaseTime":"2014-07-23T13:15:42+00:00"},{"id":"14w29b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/55f170c41313f25eb4ec8a4a52cc477c8da00178/14w29b.json","time":"2019-06-28T07:08:15+00:00","releaseTime":"2014-07-16T17:27:40+00:00"},{"id":"14w29a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/5222c2bfda606abf4c181bd4d2da5c2f583da9cb/14w29a.json","time":"2019-06-28T07:08:15+00:00","releaseTime":"2014-07-16T15:18:17+00:00"},{"id":"14w28b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/82ef4b981d95ccab9e7e5fadef82c89dfebf9604/14w28b.json","time":"2019-06-28T07:08:15+00:00","releaseTime":"2014-07-10T14:28:48+00:00"},{"id":"14w28a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/1bb62510021eb93df67c5ead257d829c21064911/14w28a.json","time":"2019-06-28T07:08:15+00:00","releaseTime":"2014-07-09T15:42:36+00:00"},{"id":"14w27b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/551af51dcb3c047908f4a175233436f32b56b1c7/14w27b.json","time":"2019-06-28T07:08:14+00:00","releaseTime":"2014-07-02T18:34:56+00:00"},{"id":"14w27a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/4e4033a046bca69c81d57555d372d2c89f5d8c33/14w27a.json","time":"2019-06-28T07:08:14+00:00","releaseTime":"2014-07-02T16:07:20+00:00"},{"id":"14w26c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/fe4a2cfb1ee0ddbeebcb227a9ae9d871a0673f7f/14w26c.json","time":"2019-06-28T07:08:14+00:00","releaseTime":"2014-06-26T15:05:03+00:00"},{"id":"14w26b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f4c2e4092c1a97a09fd9b7a389c30359fe4fbefe/14w26b.json","time":"2019-06-28T07:08:14+00:00","releaseTime":"2014-06-25T15:08:39+00:00"},{"id":"14w26a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/140b76f6e82e853412d21cfea3c2f98334e852de/14w26a.json","time":"2019-06-28T07:08:14+00:00","releaseTime":"2014-06-25T13:59:27+00:00"},{"id":"14w25b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2565bfeb09df816d4313c37af293fc8a9597c0ba/14w25b.json","time":"2019-06-28T07:08:14+00:00","releaseTime":"2014-06-19T12:29:48+00:00"},{"id":"14w25a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/6a1030badde86081dfa929cf3c8da92352e27310/14w25a.json","time":"2019-06-28T07:08:14+00:00","releaseTime":"2014-06-18T15:52:28+00:00"},{"id":"14w21b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ade99be51a33692842377f66f8a381165520bfa8/14w21b.json","time":"2019-06-28T07:08:14+00:00","releaseTime":"2014-05-22T15:17:55+00:00"},{"id":"14w21a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/6c5899eeb043abbc218cb74ee712d049458ad3fd/14w21a.json","time":"2019-06-28T07:08:14+00:00","releaseTime":"2014-05-22T14:44:33+00:00"},{"id":"14w20b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/069b90b7de445d8b403ee81b97477cdfa1526f8b/14w20b.json","time":"2019-06-28T07:08:13+00:00","releaseTime":"2014-05-15T16:47:21+00:00"},{"id":"14w20a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a2af33f2a37beef83a8d10832a677072415a24fc/14w20a.json","time":"2019-06-28T07:08:13+00:00","releaseTime":"2014-05-15T14:01:20+00:00"},{"id":"1.7.10","type":"release","url":"https://launchermeta.mojang.com/v1/packages/2e818dc89e364c7efcfa54bec7e873c5f00b3840/1.7.10.json","time":"2019-06-28T07:06:16+00:00","releaseTime":"2014-05-14T17:29:23+00:00"},{"id":"1.7.10-pre4","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/1aadefe92e61950c9ea178db4d562c4c1a0bb5ff/1.7.10-pre4.json","time":"2019-06-28T07:07:48+00:00","releaseTime":"2014-05-14T16:29:23+00:00"},{"id":"1.7.10-pre3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/3283163b0e4f3cbfb13f32ff3d19bd1d1c83c177/1.7.10-pre3.json","time":"2019-06-28T07:07:48+00:00","releaseTime":"2014-05-14T15:29:23+00:00"},{"id":"1.7.10-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/09d4e1fcd0b02cab2709a19558b20136268168cc/1.7.10-pre2.json","time":"2019-06-28T07:07:48+00:00","releaseTime":"2014-05-14T14:29:23+00:00"},{"id":"1.7.10-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b1832b49dbc5dae395b34cc6bb4aa32e3b450324/1.7.10-pre1.json","time":"2019-06-28T07:07:47+00:00","releaseTime":"2014-05-14T13:29:23+00:00"},{"id":"14w19a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/14bb3b1e4b05852ba81e3fccf55e36cf1b731eef/14w19a.json","time":"2019-06-28T07:08:13+00:00","releaseTime":"2014-05-08T14:24:19+00:00"},{"id":"14w18b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/1d2d5c9fb333d6f08312aeefdead9adbe041d0e6/14w18b.json","time":"2019-06-28T07:08:13+00:00","releaseTime":"2014-05-02T11:38:17+00:00"},{"id":"14w18a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/108308cc8f8d1e28710926710c123a2be4247971/14w18a.json","time":"2019-06-28T07:08:13+00:00","releaseTime":"2014-04-30T10:25:35+00:00"},{"id":"14w17a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/8ab598d1696783c449b778b641ae3c6df914b1de/14w17a.json","time":"2019-06-28T07:08:13+00:00","releaseTime":"2014-04-24T15:44:49+00:00"},{"id":"14w11b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/90f60ef6202a2f83feac88e6ae4fc18fa0c9425a/14w11b.json","time":"2019-06-28T07:08:13+00:00","releaseTime":"2014-04-14T14:36:19+00:00"},{"id":"1.7.9","type":"release","url":"https://launchermeta.mojang.com/v1/packages/930a26a3c81803e2f6b9a4069ac14c2e7aaf3b8a/1.7.9.json","time":"2019-06-28T07:06:17+00:00","releaseTime":"2014-04-14T13:29:23+00:00"},{"id":"1.7.8","type":"release","url":"https://launchermeta.mojang.com/v1/packages/b9b245eb23540c2bb1f5886b1d3a353870c8b684/1.7.8.json","time":"2019-06-28T07:06:17+00:00","releaseTime":"2014-04-09T07:58:16+00:00"},{"id":"1.7.7","type":"release","url":"https://launchermeta.mojang.com/v1/packages/ef55209910a073339aadf8394bb3504f6c03048c/1.7.7.json","time":"2019-06-28T07:06:17+00:00","releaseTime":"2014-04-09T07:52:16+00:00"},{"id":"1.7.6","type":"release","url":"https://launchermeta.mojang.com/v1/packages/4cdba7fb4ea885d508bf7469812bdcee6b490681/1.7.6.json","time":"2019-06-28T07:06:17+00:00","releaseTime":"2014-04-09T07:52:06+00:00"},{"id":"14w11a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/5fa270226ea95656860ce49fd69d408e25f62933/14w11a.json","time":"2019-06-28T07:08:13+00:00","releaseTime":"2014-03-13T14:02:50+00:00"},{"id":"1.7.6-pre2","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/8eedd564a29fbf6185d0a95d683d24e4322cb884/1.7.6-pre2.json","time":"2019-06-28T07:07:48+00:00","releaseTime":"2014-03-08T11:00:01+00:00"},{"id":"1.7.6-pre1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ca0399bf77ba4598018eb81a89897b57ae2b22ab/1.7.6-pre1.json","time":"2019-06-28T07:07:48+00:00","releaseTime":"2014-03-08T11:00:00+00:00"},{"id":"14w10c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/d0bf7b7151f2f9bbadad8b095bb0f06bd22c28b9/14w10c.json","time":"2019-06-28T07:08:13+00:00","releaseTime":"2014-03-07T13:49:55+00:00"},{"id":"14w10b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/9388d70d55a06ebf7cfe0b602622f696e33676d7/14w10b.json","time":"2019-06-28T07:08:12+00:00","releaseTime":"2014-03-06T16:25:39+00:00"},{"id":"14w10a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f857660a1be0a034e58e79bce8acfd846fd38cd2/14w10a.json","time":"2019-06-28T07:08:12+00:00","releaseTime":"2014-03-06T14:23:04+00:00"},{"id":"14w08a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/efabf06c42017d6e108952beb19f1e505eedafd6/14w08a.json","time":"2019-06-28T07:08:12+00:00","releaseTime":"2014-02-26T17:00:00+00:00"},{"id":"1.7.5","type":"release","url":"https://launchermeta.mojang.com/v1/packages/a0481eaa9979795bb567398a02cc3d7a3775403a/1.7.5.json","time":"2019-06-28T07:06:17+00:00","releaseTime":"2014-02-26T09:22:17+00:00"},{"id":"14w07a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b3f18dabae1e9c1b4888e26f2a7ee0fc4ca13cdd/14w07a.json","time":"2019-06-28T07:08:12+00:00","releaseTime":"2014-02-14T11:05:07+00:00"},{"id":"14w06b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2bc8fbcea17ac7a3a950c313ce7e9a6e4ae297c4/14w06b.json","time":"2019-06-28T07:08:12+00:00","releaseTime":"2014-02-06T17:30:42+00:00"},{"id":"14w06a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/0bc79bdfdf67e18e5786f701f460b19ee4af50a4/14w06a.json","time":"2019-06-28T07:08:12+00:00","releaseTime":"2014-02-06T14:30:17+00:00"},{"id":"14w05b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ce7fca43310f73f6532c6f8f94f850a86532ae80/14w05b.json","time":"2019-06-28T07:08:12+00:00","releaseTime":"2014-01-31T14:05:50+00:00"},{"id":"14w05a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/fb2600e556a199c81b238795ee3a3a05ddb02c59/14w05a.json","time":"2019-06-28T07:08:12+00:00","releaseTime":"2014-01-30T15:32:41+00:00"},{"id":"14w04b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b6df6484e2ae6a57f4cfd5f3da29de238846702a/14w04b.json","time":"2019-06-28T07:08:11+00:00","releaseTime":"2014-01-24T15:48:46+00:00"},{"id":"14w04a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/3be1cf3e471a51e4a8346337a58d9379175f4bd4/14w04a.json","time":"2019-06-28T07:08:11+00:00","releaseTime":"2014-01-23T15:26:13+00:00"},{"id":"14w03b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/44d7d06106c00398e96ae0ec46b936e4f22fd8be/14w03b.json","time":"2019-06-28T07:08:11+00:00","releaseTime":"2014-01-16T16:36:19+00:00"},{"id":"14w03a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/6ee35b2eb136f1ec3246ff71e357149be156e64f/14w03a.json","time":"2019-06-28T07:08:11+00:00","releaseTime":"2014-01-16T14:45:13+00:00"},{"id":"14w02c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/965c31544504b579f64926d0ac3c611de5c0d84c/14w02c.json","time":"2019-06-28T07:08:11+00:00","releaseTime":"2014-01-10T15:42:36+00:00"},{"id":"14w02b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/7d7d7362484c27ba4df5250e55c6ce7f9ee507cc/14w02b.json","time":"2019-06-28T07:08:11+00:00","releaseTime":"2014-01-09T15:45:55+00:00"},{"id":"14w02a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/32084e58b99ce15a667ed1ef39c3366c84350651/14w02a.json","time":"2019-06-28T07:08:11+00:00","releaseTime":"2014-01-09T14:44:41+00:00"},{"id":"1.7.4","type":"release","url":"https://launchermeta.mojang.com/v1/packages/b06faa2910235ba9ecfab434e54e04a0d5f6187d/1.7.4.json","time":"2019-06-28T07:06:16+00:00","releaseTime":"2013-12-09T12:28:10+00:00"},{"id":"1.7.3","type":"release","url":"https://launchermeta.mojang.com/v1/packages/6ad7a69e99996ddb88824a764a869c7ea410ffb3/1.7.3.json","time":"2019-06-28T07:06:16+00:00","releaseTime":"2013-12-06T13:55:34+00:00"},{"id":"13w49a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ba7947f99ec9a16b9d2f2e1f2bef7d71c523ea54/13w49a.json","time":"2019-06-28T07:08:11+00:00","releaseTime":"2013-12-05T14:34:41+00:00"},{"id":"13w48b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/6d3d2f6b7fa888b2c6c5bd457e2b6baaf4405faf/13w48b.json","time":"2019-06-28T07:08:10+00:00","releaseTime":"2013-11-26T18:36:08+00:00"},{"id":"13w48a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/e1330699e090befe8deb8b4606dbc21e59ed8e5b/13w48a.json","time":"2019-06-28T07:08:10+00:00","releaseTime":"2013-11-25T16:53:39+00:00"},{"id":"13w47e","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/880bdce57f43afb0d5a083fba090c99e7b99f514/13w47e.json","time":"2019-06-28T07:08:10+00:00","releaseTime":"2013-11-22T15:16:38+00:00"},{"id":"13w47d","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/0ccb6fd168823b91d26934e43af326665ba48963/13w47d.json","time":"2019-06-28T07:08:10+00:00","releaseTime":"2013-11-22T13:51:15+00:00"},{"id":"13w47c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/dd754b7d7f95b056556a6044ab4de763a9bead73/13w47c.json","time":"2019-06-28T07:08:10+00:00","releaseTime":"2013-11-21T17:10:33+00:00"},{"id":"13w47b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/231f5e4d3df49da8b84e71cae2d90d14b575460e/13w47b.json","time":"2019-06-28T07:08:10+00:00","releaseTime":"2013-11-21T16:57:41+00:00"},{"id":"13w47a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b871593e6fe9faf9e1557b4cfe272e7c1e05fd20/13w47a.json","time":"2019-06-28T07:08:10+00:00","releaseTime":"2013-11-21T15:59:58+00:00"},{"id":"1.7.2","type":"release","url":"https://launchermeta.mojang.com/v1/packages/83a7d28760ed623225e7cb2e29db140cc68540e8/1.7.2.json","time":"2019-06-28T07:06:16+00:00","releaseTime":"2013-10-25T13:00:00+00:00"},{"id":"1.7.1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/4772d17d3ffdc243d22d136ccec04b0d1093bb25/1.7.1.json","time":"2019-06-28T07:07:47+00:00","releaseTime":"2013-10-23T12:01:07+00:00"},{"id":"1.7","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/5d831c6ad5d1d3547168e981f7786555ae154c05/1.7.json","time":"2019-06-28T07:07:48+00:00","releaseTime":"2013-10-22T15:04:05+00:00"},{"id":"13w43a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/6c1693fe1f674b821699782ddee5370f432041fc/13w43a.json","time":"2019-06-28T07:08:10+00:00","releaseTime":"2013-10-21T16:34:47+00:00"},{"id":"13w42b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b4010b058dd098ae49ead32d1c03deda74a0285a/13w42b.json","time":"2019-06-28T07:08:10+00:00","releaseTime":"2013-10-18T16:34:08+00:00"},{"id":"13w42a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/d6d9998807948f87aaf279dd0555dfdbf1c3baaf/13w42a.json","time":"2019-06-28T07:08:09+00:00","releaseTime":"2013-10-17T18:33:05+00:00"},{"id":"13w41b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/e0b86f8f6029b81a980afeb661774aa7ebb9067b/13w41b.json","time":"2019-06-28T07:08:09+00:00","releaseTime":"2013-10-11T15:09:17+00:00"},{"id":"13w41a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b81e1a63c1e420f5fb5c9b5c0aaa5bc7eb187e7c/13w41a.json","time":"2019-06-28T07:08:09+00:00","releaseTime":"2013-10-10T14:21:43+00:00"},{"id":"13w39b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f2bb7d91452ebcd98bc77b0e69d279b1146c02a4/13w39b.json","time":"2019-06-28T07:08:09+00:00","releaseTime":"2013-09-27T12:15:58+00:00"},{"id":"13w39a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2f4e00c7f6e3bc4a707c027ae2b527bcede4adda/13w39a.json","time":"2019-06-28T07:08:09+00:00","releaseTime":"2013-09-26T15:11:19+00:00"},{"id":"13w38c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/a9e87e0699f19fea280878f5deb744c5d5d3ccb1/13w38c.json","time":"2019-06-28T07:08:09+00:00","releaseTime":"2013-09-20T15:11:34+00:00"},{"id":"13w38b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/6f426be1993b140ab5d10459c91eb1f542d58c82/13w38b.json","time":"2019-06-28T07:08:09+00:00","releaseTime":"2013-09-20T13:45:40+00:00"},{"id":"13w38a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/e6dc1d9f9c8efeec67af438d5bf61be082f6e8a4/13w38a.json","time":"2019-06-28T07:08:09+00:00","releaseTime":"2013-09-19T16:34:21+00:00"},{"id":"1.6.4","type":"release","url":"https://launchermeta.mojang.com/v1/packages/b71bae449192fbbe1582ff32fb3765edf0b9b0a8/1.6.4.json","time":"2019-06-28T07:06:16+00:00","releaseTime":"2013-09-19T15:52:37+00:00"},{"id":"1.6.3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/903d6ba1bc87c301d88fa418f8b33446201c7d4e/1.6.3.json","time":"2019-06-28T07:07:47+00:00","releaseTime":"2013-09-13T10:54:41+00:00"},{"id":"13w37b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b8d28154ee056af6af3c8c37815418fe0e9f34f8/13w37b.json","time":"2019-06-28T07:08:08+00:00","releaseTime":"2013-09-13T10:54:41+00:00"},{"id":"13w37a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2f33c613a4bb81ef5f56be03a8f578208ada382a/13w37a.json","time":"2019-06-28T07:08:08+00:00","releaseTime":"2013-09-12T14:23:14+00:00"},{"id":"13w36b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/4a538e23057a596fc8c7e04d8a7738d866467f51/13w36b.json","time":"2019-06-28T07:08:08+00:00","releaseTime":"2013-09-06T12:31:58+00:00"},{"id":"13w36a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/bc915c4dc167dfba92fcc0ae3aa051ae0f9f089b/13w36a.json","time":"2019-06-28T07:08:08+00:00","releaseTime":"2013-09-05T13:05:40+00:00"},{"id":"1.6.2","type":"release","url":"https://launchermeta.mojang.com/v1/packages/c0729761bf65dc58138ce508645dba1442fa78b8/1.6.2.json","time":"2019-06-28T07:06:16+00:00","releaseTime":"2013-07-05T13:09:02+00:00"},{"id":"1.6.1","type":"release","url":"https://launchermeta.mojang.com/v1/packages/7fd8e0c76f62813eb0465e31bb74b160c01472d6/1.6.1.json","time":"2019-06-28T07:06:16+00:00","releaseTime":"2013-06-28T14:48:41+00:00"},{"id":"1.6","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/20116297638f7c70cd046e25a6ac90fee4cae61a/1.6.json","time":"2019-06-28T07:07:47+00:00","releaseTime":"2013-06-25T13:08:56+00:00"},{"id":"13w26a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b349702aef5e3adaebec30c79338300423943930/13w26a.json","time":"2019-06-28T07:08:08+00:00","releaseTime":"2013-06-24T16:06:06+00:00"},{"id":"13w25c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/934788bc580ef0a19725ee5bd31f02a0b866e0bf/13w25c.json","time":"2019-06-28T07:08:08+00:00","releaseTime":"2013-06-20T15:23:37+00:00"},{"id":"13w25b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/8b7870ddd0d0b38779479ad782d65ad80e688cf7/13w25b.json","time":"2019-06-28T07:08:08+00:00","releaseTime":"2013-06-18T15:13:27+00:00"},{"id":"13w25a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/65c0e5fff89b477ac6f8ddb336f0e718d525d311/13w25a.json","time":"2019-06-28T07:08:08+00:00","releaseTime":"2013-06-17T14:08:06+00:00"},{"id":"13w24b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/e1294b52803771cfb06767c4c40dced70475cb25/13w24b.json","time":"2019-06-28T07:08:08+00:00","releaseTime":"2013-06-14T12:19:13+00:00"},{"id":"13w24a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/74666ab85cc5539f08aec638eabd63a552ed4125/13w24a.json","time":"2019-06-28T07:08:07+00:00","releaseTime":"2013-06-13T15:32:23+00:00"},{"id":"13w23b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b19c87c7bfe0c0b202f79fc4b870b0ae97b00e53/13w23b.json","time":"2019-06-28T07:08:07+00:00","releaseTime":"2013-06-08T00:32:01+00:00"},{"id":"13w23a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/400a136ff102882dfa9bb8990aef32b81309d46a/13w23a.json","time":"2019-06-28T07:08:07+00:00","releaseTime":"2013-06-07T16:04:20+00:00"},{"id":"13w22a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f8277e55fae1555de47b44f5e6620f13b79fbe4e/13w22a.json","time":"2019-06-28T07:08:07+00:00","releaseTime":"2013-05-30T14:38:40+00:00"},{"id":"13w21b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/eab4bc12a78d862fadb36192c5351e35888eab15/13w21b.json","time":"2019-06-28T07:08:07+00:00","releaseTime":"2013-05-27T08:50:42+00:00"},{"id":"13w21a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/ff59021171bd73aa155e40f84a924e1ab3f5307d/13w21a.json","time":"2019-06-28T07:08:07+00:00","releaseTime":"2013-05-23T15:38:28+00:00"},{"id":"13w19a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/9360f33fa1391cbbfead0e0033c5a1e763f28d19/13w19a.json","time":"2019-06-28T07:08:07+00:00","releaseTime":"2013-05-10T14:48:02+00:00"},{"id":"13w18c","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/79ab628c68cefd8daa25d186f7961299ef4e63a9/13w18c.json","time":"2019-06-28T07:08:07+00:00","releaseTime":"2013-05-03T09:19:35+00:00"},{"id":"13w18b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/2eea88342657ab8327af70ac2e1416859e0ef02a/13w18b.json","time":"2019-06-28T07:08:07+00:00","releaseTime":"2013-05-02T17:12:25+00:00"},{"id":"13w18a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/0fdbf2d4561027558ba9475c5d318540c743dec9/13w18a.json","time":"2019-06-28T07:08:06+00:00","releaseTime":"2013-05-02T15:45:59+00:00"},{"id":"13w17a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/f65b6bd3c813d67b026a3c9ec12e3280c495cf87/13w17a.json","time":"2019-06-28T07:08:06+00:00","releaseTime":"2013-04-25T15:50:00+00:00"},{"id":"1.5.2","type":"release","url":"https://launchermeta.mojang.com/v1/packages/a611948faa091ef3a0af43d39f77589c5e402170/1.5.2.json","time":"2019-06-28T07:06:16+00:00","releaseTime":"2013-04-25T15:45:00+00:00"},{"id":"13w16b","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/b2c1241c6ca9d119a9f2df431cdf18a56f883d0d/13w16b.json","time":"2019-06-28T07:08:06+00:00","releaseTime":"2013-04-23T21:51:22+00:00"},{"id":"13w16a","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/7efbf7a86354b08f0a5011c96752c92cabb2e67c/13w16a.json","time":"2019-06-28T07:08:06+00:00","releaseTime":"2013-04-21T12:49:30+00:00"},{"id":"1.5.1","type":"release","url":"https://launchermeta.mojang.com/v1/packages/46b50f586db97821f22d2c94914c3a31f733a264/1.5.1.json","time":"2019-06-28T07:06:16+00:00","releaseTime":"2013-03-20T10:00:00+00:00"},{"id":"1.5","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/00fa1c125d5ad5ccdbc55f1d1b53b6f52c85bd22/1.5.json","time":"2019-06-28T07:07:47+00:00","releaseTime":"2013-03-06T22:00:00+00:00"},{"id":"1.4.7","type":"release","url":"https://launchermeta.mojang.com/v1/packages/89802d57ccee3d03ec59d2ab1f44386234adb399/1.4.7.json","time":"2019-06-28T07:06:15+00:00","releaseTime":"2012-12-27T22:00:00+00:00"},{"id":"1.4.6","type":"release","url":"https://launchermeta.mojang.com/v1/packages/a7d02971582fcdf14ea275cc549cb57604a37079/1.4.6.json","time":"2019-06-28T07:06:15+00:00","releaseTime":"2012-12-19T22:00:00+00:00"},{"id":"1.4.5","type":"release","url":"https://launchermeta.mojang.com/v1/packages/19555cce1f6d04e2b417ac2e9e06b6b752d5a2de/1.4.5.json","time":"2019-06-28T07:06:15+00:00","releaseTime":"2012-12-19T22:00:00+00:00"},{"id":"1.4.4","type":"release","url":"https://launchermeta.mojang.com/v1/packages/578d09d5753e590ea043a68bdaaea45a5b9711ab/1.4.4.json","time":"2019-06-28T07:06:15+00:00","releaseTime":"2012-12-13T22:00:00+00:00"},{"id":"1.4.3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/180deba5c263367e914217be0701bd9e1a44f13b/1.4.3.json","time":"2019-06-28T07:07:47+00:00","releaseTime":"2012-11-30T22:00:00+00:00"},{"id":"1.4.2","type":"release","url":"https://launchermeta.mojang.com/v1/packages/aec7405cf74ae5f79b13f6e8c88f66920eac0e1b/1.4.2.json","time":"2019-06-28T07:06:15+00:00","releaseTime":"2012-11-24T22:00:00+00:00"},{"id":"1.4.1","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/859f584890b4db227f267026510c6ac2a5076d94/1.4.1.json","time":"2019-06-28T07:07:47+00:00","releaseTime":"2012-11-22T22:00:00+00:00"},{"id":"1.4","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/070986801bc1d42eac872758cf12f00afa7b5f35/1.4.json","time":"2019-06-28T07:07:47+00:00","releaseTime":"2012-11-18T22:00:00+00:00"},{"id":"1.3.2","type":"release","url":"https://launchermeta.mojang.com/v1/packages/2bd0ca9b77465a29df4b9449772d008f8724dd19/1.3.2.json","time":"2019-06-28T07:06:15+00:00","releaseTime":"2012-08-15T22:00:00+00:00"},{"id":"1.3.1","type":"release","url":"https://launchermeta.mojang.com/v1/packages/be773d2fff5c6e4db9929ae4ea780f8837323b6b/1.3.1.json","time":"2019-06-28T07:06:15+00:00","releaseTime":"2012-07-31T22:00:00+00:00"},{"id":"1.3","type":"snapshot","url":"https://launchermeta.mojang.com/v1/packages/aeb1bb40dc59420433ae46a0f133392508218bbe/1.3.json","time":"2019-06-28T07:07:47+00:00","releaseTime":"2012-07-25T22:00:00+00:00"},{"id":"1.2.5","type":"release","url":"https://launchermeta.mojang.com/v1/packages/886723c6385e62bb8dbe8026abf685140602404b/1.2.5.json","time":"2019-06-28T07:06:15+00:00","releaseTime":"2012-03-29T22:00:00+00:00"},{"id":"1.2.4","type":"release","url":"https://launchermeta.mojang.com/v1/packages/3cc81a28957e8c7d94bdd4f6b2c51ef8cae54f9b/1.2.4.json","time":"2019-06-28T07:06:15+00:00","releaseTime":"2012-03-21T22:00:00+00:00"},{"id":"1.2.3","type":"release","url":"https://launchermeta.mojang.com/v1/packages/4100a29330f76c93ef3bdc47d11fa016fd73de99/1.2.3.json","time":"2019-06-28T07:06:14+00:00","releaseTime":"2012-03-01T22:00:00+00:00"},{"id":"1.2.2","type":"release","url":"https://launchermeta.mojang.com/v1/packages/897ce0e56d1cecc9e720f1934c09ea395008aa9e/1.2.2.json","time":"2019-06-28T07:06:14+00:00","releaseTime":"2012-02-29T22:00:01+00:00"},{"id":"1.2.1","type":"release","url":"https://launchermeta.mojang.com/v1/packages/dc5f9e134da9e18a2db42ddc246aba5cdfe28d3c/1.2.1.json","time":"2019-06-28T07:06:14+00:00","releaseTime":"2012-02-29T22:00:00+00:00"},{"id":"1.1","type":"release","url":"https://launchermeta.mojang.com/v1/packages/1c1aaa3dea5155b549d4baf3491e3f5f564c3b8b/1.1.json","time":"2019-06-28T07:05:45+00:00","releaseTime":"2012-01-11T22:00:00+00:00"},{"id":"1.0","type":"release","url":"https://launchermeta.mojang.com/v1/packages/edfc56a64dfc6430665d745264732db53b0d1b41/1.0.json","time":"2019-06-28T07:05:45+00:00","releaseTime":"2011-11-17T22:00:00+00:00"},{"id":"b1.8.1","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/5b5a652a385b3d04af8e05bb773696a227ebc300/b1.8.1.json","time":"2019-06-28T07:05:45+00:00","releaseTime":"2011-09-18T22:00:00+00:00"},{"id":"b1.8","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/c2ce53a6d847e3c3efb640dc7d32e47e72e0a24f/b1.8.json","time":"2019-06-28T07:05:45+00:00","releaseTime":"2011-09-14T22:00:00+00:00"},{"id":"b1.7.3","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/0de35233bea254fd0011cceb4aa96e0a32b7efd2/b1.7.3.json","time":"2019-06-28T07:05:45+00:00","releaseTime":"2011-07-07T22:00:00+00:00"},{"id":"b1.7.2","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/b9ac061f45d78c16739c95871d1540c681a187c8/b1.7.2.json","time":"2019-06-28T07:05:45+00:00","releaseTime":"2011-06-30T22:00:00+00:00"},{"id":"b1.7","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/3b7900fbef699471069015beef2a0d62cb2efabf/b1.7.json","time":"2019-06-28T07:05:45+00:00","releaseTime":"2011-06-29T22:00:00+00:00"},{"id":"b1.6.6","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/2c39299d7841e5273f5a6347373ba89eb48149d2/b1.6.6.json","time":"2019-06-28T07:05:44+00:00","releaseTime":"2011-05-30T22:00:00+00:00"},{"id":"b1.6.5","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/f52059e5de7e06cbceba3642895005a36c40a6ef/b1.6.5.json","time":"2019-06-28T07:05:44+00:00","releaseTime":"2011-05-27T22:00:00+00:00"},{"id":"b1.6.4","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/3a6546e2e4be5492c974359880f5cd6f1c513478/b1.6.4.json","time":"2019-06-28T07:05:44+00:00","releaseTime":"2011-05-25T22:00:04+00:00"},{"id":"b1.6.3","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/4aa947cc55a28139e06ba6cde47b2c5aa3d9941c/b1.6.3.json","time":"2019-06-28T07:05:44+00:00","releaseTime":"2011-05-25T22:00:03+00:00"},{"id":"b1.6.2","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/299360b97a57c73c0a6f258313200f40a37ab758/b1.6.2.json","time":"2019-06-28T07:05:44+00:00","releaseTime":"2011-05-25T22:00:02+00:00"},{"id":"b1.6.1","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/72fc5a50e6a2fc9cdb5d77dcaa1f4cd4391536d3/b1.6.1.json","time":"2019-06-28T07:05:44+00:00","releaseTime":"2011-05-25T22:00:01+00:00"},{"id":"b1.6","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/70c6be33812e5a030db15b28ccd72d30a5dcbca7/b1.6.json","time":"2019-06-28T07:05:44+00:00","releaseTime":"2011-05-25T22:00:00+00:00"},{"id":"b1.5_01","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/cda4fc0e6f35c8645a013045be7c746e1a5b63d3/b1.5_01.json","time":"2019-06-28T07:05:44+00:00","releaseTime":"2011-04-19T22:00:00+00:00"},{"id":"b1.5","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/cd33026e81d260495f859a446a1f17e3071a17ea/b1.5.json","time":"2019-06-28T07:05:44+00:00","releaseTime":"2011-04-18T22:00:00+00:00"},{"id":"b1.4_01","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/7a7fbff959b9576845d83b215cc82ecf6bca5bcf/b1.4_01.json","time":"2019-06-28T07:05:43+00:00","releaseTime":"2011-04-04T22:00:00+00:00"},{"id":"b1.4","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/ce8cd5c165f2941d343cd98ec76a5b93d9a95c8c/b1.4.json","time":"2019-06-28T07:05:43+00:00","releaseTime":"2011-03-30T22:00:00+00:00"},{"id":"b1.3_01","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/f551611d75278e2847cca77421a51b99f4bb32de/b1.3_01.json","time":"2019-06-28T07:05:43+00:00","releaseTime":"2011-02-22T22:00:00+00:00"},{"id":"b1.3b","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/a803c5a24b04ccab17269183b872cdaa38b32ae3/b1.3b.json","time":"2019-06-28T07:05:43+00:00","releaseTime":"2011-02-21T22:00:00+00:00"},{"id":"b1.2_02","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/afeabd62ef6bab19c8d570ab39a5e4161b27b85d/b1.2_02.json","time":"2019-06-28T07:05:43+00:00","releaseTime":"2011-01-20T22:00:00+00:00"},{"id":"b1.2_01","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/e9ea31d80bb8979bf3042165094d2e10b2899eaf/b1.2_01.json","time":"2019-06-28T07:05:43+00:00","releaseTime":"2011-01-13T22:00:00+00:00"},{"id":"b1.2","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/703f0c0797d0b83dac8304b1c35ee4dcee6a2413/b1.2.json","time":"2019-06-28T07:05:43+00:00","releaseTime":"2011-01-12T22:00:00+00:00"},{"id":"b1.1_02","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/219e087b54dc2ca9a51a0204238cccaa035b5cef/b1.1_02.json","time":"2019-06-28T07:05:43+00:00","releaseTime":"2010-12-21T22:00:01+00:00"},{"id":"b1.1_01","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/d0d10f21a0f8115bdfbc2f0ddef2d93833af2e9d/b1.1_01.json","time":"2019-06-28T07:05:43+00:00","releaseTime":"2010-12-21T22:00:00+00:00"},{"id":"b1.0.2","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/f8d933ed690495b66f76d0a5045e40c18881a26a/b1.0.2.json","time":"2019-06-28T07:05:42+00:00","releaseTime":"2010-12-20T22:00:00+00:00"},{"id":"b1.0_01","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/c7559faa3f520837456b2a3736c663a856812049/b1.0_01.json","time":"2019-06-28T07:05:42+00:00","releaseTime":"2010-12-19T22:00:01+00:00"},{"id":"b1.0","type":"old_beta","url":"https://launchermeta.mojang.com/v1/packages/5be70efae7eea5f18ce164fb264eaa9563a054ee/b1.0.json","time":"2019-06-28T07:05:42+00:00","releaseTime":"2010-12-19T22:00:00+00:00"},{"id":"a1.2.6","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/d385e176aa7d3d3702bac78ad1ba906a77de13df/a1.2.6.json","time":"2019-06-28T07:05:41+00:00","releaseTime":"2010-12-02T22:00:00+00:00"},{"id":"a1.2.5","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/491a4961f00770bd130206c013795f35af948493/a1.2.5.json","time":"2019-06-28T07:05:41+00:00","releaseTime":"2010-11-30T22:00:00+00:00"},{"id":"a1.2.4_01","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/e802a257031c5b9297c971599cc2573c2efece2c/a1.2.4_01.json","time":"2019-06-28T07:05:41+00:00","releaseTime":"2010-11-29T22:00:00+00:00"},{"id":"a1.2.3_04","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/467403a159661d486fbe49480faf0909ea533759/a1.2.3_04.json","time":"2019-06-28T07:05:41+00:00","releaseTime":"2010-11-25T22:00:00+00:00"},{"id":"a1.2.3_02","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/31fa028661857f2e3d3732d07a6d36ec21d6dbdc/a1.2.3_02.json","time":"2019-06-28T07:05:41+00:00","releaseTime":"2010-11-24T22:00:00+00:00"},{"id":"a1.2.3_01","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/2dbccc4579a4481dc8d72a962d396de044648522/a1.2.3_01.json","time":"2019-06-28T07:05:40+00:00","releaseTime":"2010-11-23T22:00:01+00:00"},{"id":"a1.2.3","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/48f077bf27e0a01a0bb2051e0ac17a96693cb730/a1.2.3.json","time":"2019-06-28T07:05:40+00:00","releaseTime":"2010-11-23T22:00:00+00:00"},{"id":"a1.2.2b","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/0fbd340ae9087db32535ed0fb2d119240e7e0aaa/a1.2.2b.json","time":"2019-06-28T07:05:40+00:00","releaseTime":"2010-11-09T22:00:01+00:00"},{"id":"a1.2.2a","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/6679a974769ad2c6b88025ccbb60c72612dcee1f/a1.2.2a.json","time":"2019-06-28T07:05:40+00:00","releaseTime":"2010-11-09T22:00:00+00:00"},{"id":"a1.2.1_01","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/79e993b71f867e777a0ac9e2816bfd3df5c1aaed/a1.2.1_01.json","time":"2019-06-28T07:05:40+00:00","releaseTime":"2010-11-04T22:00:01+00:00"},{"id":"a1.2.1","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/f601478f5b0bf55ba0a302a4d1a8ce402c9311c1/a1.2.1.json","time":"2019-06-28T07:05:40+00:00","releaseTime":"2010-11-04T22:00:00+00:00"},{"id":"a1.2.0_02","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/48465dfa2e2066e3b06e8fca934f2bbd7d03e65c/a1.2.0_02.json","time":"2019-06-28T07:05:40+00:00","releaseTime":"2010-11-03T22:00:00+00:00"},{"id":"a1.2.0_01","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/e31556ae6f925d4dc7a06a5110cce731eca6eaa8/a1.2.0_01.json","time":"2019-06-28T07:05:40+00:00","releaseTime":"2010-10-30T22:00:00+00:00"},{"id":"a1.2.0","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/a0e7c34fba8c11fa8b84a56a01ed8505ad34b52a/a1.2.0.json","time":"2019-06-28T07:05:39+00:00","releaseTime":"2010-10-29T22:00:00+00:00"},{"id":"a1.1.2_01","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/c28a71888f39178cfc6f882fd62f49de920d138e/a1.1.2_01.json","time":"2019-06-28T07:05:39+00:00","releaseTime":"2010-09-22T22:00:00+00:00"},{"id":"a1.1.2","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/1231fefa206b10993e4b77b13f86fc72759db038/a1.1.2.json","time":"2019-06-28T07:05:39+00:00","releaseTime":"2010-09-19T22:00:00+00:00"},{"id":"a1.1.0","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/a30685ddf58121f25dd845e5361a3d262409489d/a1.1.0.json","time":"2019-06-28T07:05:39+00:00","releaseTime":"2010-09-12T22:00:00+00:00"},{"id":"a1.0.17_04","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/7c85d4575c9cc951135c3e6e958e1fcb2ed4e4ae/a1.0.17_04.json","time":"2019-06-28T07:05:39+00:00","releaseTime":"2010-08-22T22:00:00+00:00"},{"id":"a1.0.17_02","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/54d1b6731a61a0b513ec0f677b58249be6c94086/a1.0.17_02.json","time":"2019-06-28T07:05:39+00:00","releaseTime":"2010-08-19T22:00:00+00:00"},{"id":"a1.0.16","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/139fcc1a590a1166b872046bf4b82cfb04452061/a1.0.16.json","time":"2019-06-28T07:05:38+00:00","releaseTime":"2010-08-11T22:00:00+00:00"},{"id":"a1.0.15","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/786cd66bd91d3bd8ebd5d7fb10ec63daf671b646/a1.0.15.json","time":"2019-06-28T07:05:38+00:00","releaseTime":"2010-08-03T22:00:00+00:00"},{"id":"a1.0.14","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/eff58a647f38df437241e769a9703baa40e0efd8/a1.0.14.json","time":"2019-06-28T07:05:38+00:00","releaseTime":"2010-07-29T22:00:00+00:00"},{"id":"a1.0.11","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/3467dbde729f4e43047e54627ca20c82c9ee9a66/a1.0.11.json","time":"2019-06-28T07:05:38+00:00","releaseTime":"2010-07-22T22:00:00+00:00"},{"id":"a1.0.5_01","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/269ea3fdb671777a7bd0e97d4046cc27dc909694/a1.0.5_01.json","time":"2019-06-28T07:05:39+00:00","releaseTime":"2010-07-12T22:00:00+00:00"},{"id":"a1.0.4","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/a1f71c0a68d59c0b6570073b440fb55ff889ba5a/a1.0.4.json","time":"2019-06-28T07:05:39+00:00","releaseTime":"2010-07-08T22:00:00+00:00"},{"id":"inf-20100618","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/065ce5795aaf172080a4975cefac0d248bee7a3b/inf-20100618.json","time":"2019-06-28T07:05:42+00:00","releaseTime":"2010-06-15T22:00:00+00:00"},{"id":"c0.30_01c","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/0bb9bdebc3e124818fd31779a4bb394283050a02/c0.30_01c.json","time":"2019-06-28T07:05:42+00:00","releaseTime":"2009-12-21T22:00:00+00:00"},{"id":"c0.0.13a","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/5d77dd27f9684b4cbfbecc29a2c8c28d36a5e9c2/c0.0.13a.json","time":"2019-06-28T07:05:41+00:00","releaseTime":"2009-05-30T22:00:00+00:00"},{"id":"c0.0.13a_03","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/3e038a3d4ce26771a8019c8c348a18844b950fdc/c0.0.13a_03.json","time":"2019-06-28T07:05:41+00:00","releaseTime":"2009-05-21T22:00:00+00:00"},{"id":"c0.0.11a","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/d700384628b420acbe14388efc3b563e85ff7961/c0.0.11a.json","time":"2019-06-28T07:05:41+00:00","releaseTime":"2009-05-16T22:00:00+00:00"},{"id":"rd-161348","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/a937d17cca60af0a7d45d04b49a849af16b08a28/rd-161348.json","time":"2019-06-28T07:05:42+00:00","releaseTime":"2009-05-16T11:48:00+00:00"},{"id":"rd-160052","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/c33dd04acfdbf34dcdfcca64db8545339ea24f02/rd-160052.json","time":"2019-06-28T07:05:42+00:00","releaseTime":"2009-05-15T22:52:00+00:00"},{"id":"rd-20090515","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/1bcd01f323df5c5092e9f0967b3d310d5bc0013a/rd-20090515.json","time":"2019-06-28T07:05:42+00:00","releaseTime":"2009-05-14T22:00:00+00:00"},{"id":"rd-132328","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/77baa48d9cbbc6c3165c294e5bcdab2ca6903d57/rd-132328.json","time":"2019-06-28T07:05:42+00:00","releaseTime":"2009-05-13T21:28:00+00:00"},{"id":"rd-132211","type":"old_alpha","url":"https://launchermeta.mojang.com/v1/packages/0f2a46082313d0ec67972f9f63c3fa6591f9bb85/rd-132211.json","time":"2019-06-28T07:05:42+00:00","releaseTime":"2009-05-13T20:11:00+00:00"}] + */ + private LatestBean latest; + + private List versions; + + public LatestBean getLatest() { + return latest; + } + + public void setLatest(LatestBean latest) { + this.latest = latest; + } + + public List getVersions() { + return versions; + } + + public void setVersions(List versions) { + this.versions = versions; + } + + public static class LatestBean { + /** + * release : 1.15.1 snapshot : 1.15.1 + */ + private String release; + + private String snapshot; + + public String getRelease() { + return release; + } + + public void setRelease(String release) { + this.release = release; + } + + public String getSnapshot() { + return snapshot; + } + + public void setSnapshot(String snapshot) { + this.snapshot = snapshot; + } + + } + + public static class VersionsBean { + /** + * id : 1.15.1 type : release url : + * https://launchermeta.mojang.com/v1/packages/57c1b5f7376febf269f7e555f96def8f1a43bb76/1.15.1.json + * time : 2019-12-16T10:33:36+00:00 releaseTime : 2019-12-16T10:29:47+00:00 + */ + private String id; + + private String type; + + private String url; + + private String time; + + private String releaseTime; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + public String getReleaseTime() { + return releaseTime; + } + + public void setReleaseTime(String releaseTime) { + this.releaseTime = releaseTime; + } + + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/EngineHubPaster.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/EngineHubPaster.java new file mode 100644 index 0000000..748c442 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/EngineHubPaster.java @@ -0,0 +1,33 @@ +/* + * This file is a part of project QuickShop, the name is EngineHubPaster.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util.paste; + +import org.jetbrains.annotations.NotNull; + +public class EngineHubPaster implements PasteInterface { + @Override + public String pasteTheText(@NotNull String text) throws Exception { + org.abc.A.L.com.sk89q.worldedit.util.paste.EngineHubPaster + paster = + new org.abc.A.L.com.sk89q.worldedit.util.paste.EngineHubPaster(); + return paster.paste(text).call().toString(); + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/Paste.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/Paste.java new file mode 100644 index 0000000..5ad938b --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/Paste.java @@ -0,0 +1,398 @@ +/* + * This file is a part of project QuickShop, the name is Paste.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util.paste; + +import java.io.File; +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import lombok.AllArgsConstructor; +import lombok.SneakyThrows; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.abc.A.F.Economy; +import org.abc.A.F.EconomyCore; +import org.abc.A.F.Economy_Vault; +import org.abc.A.QuickShop; +import org.abc.A.util.Util; + +/** + * A util to generate a paste report and upload it to EngineHub/Ubuntu Paste + */ +@AllArgsConstructor +public class Paste { + private QuickShop plugin; + + /** + * Create a server infomation paste + * + * @return The paste result content. + */ + @SneakyThrows + public @NotNull String genNewPaste() { + StringBuilder finalReport = new StringBuilder(); + finalReport.append("###############################\n"); + finalReport.append("QuickShop-Reremake Paste Result\n"); + finalReport.append("###############################\n"); + finalReport.append("\n"); + finalReport.append("\n"); + finalReport.append("================================================\n"); + finalReport.append("QuickShop:\n"); + finalReport.append("\tVersion: ").append(QuickShop.getVersion()).append("\n"); + finalReport.append("\tFork: ").append(QuickShop.getFork()).append("\n"); + finalReport.append("\tServer ID: ").append(plugin.getServerUniqueID()).append("\n"); + finalReport + .append("\tOpenInv Hook: ") + .append(plugin.getOpenInvPlugin() == null ? "Disabled" : "Enabled") + .append("\n"); + finalReport.append("\tEconomy System: "); + try { + EconomyCore economyCore = plugin.getEconomy().getCore(); + switch (Economy.getNowUsing()) { + case VAULT: + finalReport + .append("Vault") + .append("%") + .append(((Economy_Vault) economyCore).getProviderName()); + break; + case RESERVE: + finalReport.append("Reserve").append("%").append("No details"); + break; + case UNKNOWN: + finalReport.append("Unknown").append("%").append("Unknown error"); + break; + } + } catch (Exception e) { + finalReport.append("Unknown").append("%").append("Unknown error"); + } + + finalReport.append("\n"); + finalReport.append("================================================\n"); + finalReport.append("System:\n"); + finalReport.append("\tOS: ").append(System.getProperty("os.name")).append("\n"); + finalReport.append("\tArch: ").append(System.getProperty("os.arch")).append("\n"); + finalReport.append("\tVersion: ").append(System.getProperty("os.version")).append("\n"); + finalReport.append("\tCores: ").append(Runtime.getRuntime().availableProcessors()).append("\n"); + finalReport.append("================================================\n"); + finalReport.append("Server:\n"); + finalReport.append("\tName: ").append(Bukkit.getName()).append("\n"); + finalReport.append("\tServer Name: ").append(Bukkit.getServer().getName()).append("\n"); + finalReport.append("\tBuild: ").append(Bukkit.getServer().getVersion()).append("\n"); + finalReport.append("\tNMSV: ").append(Util.getNMSVersion()).append("\n"); + //noinspection deprecation + finalReport.append("\tData Version: ").append(Bukkit.getUnsafe().getDataVersion()).append("\n"); + finalReport.append("\tJava: ").append(System.getProperty("java.version")).append("\n"); + RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean(); + List arguments = runtimeMxBean.getInputArguments(); + finalReport.append("\tInput Args: ").append(Util.list2String(arguments)).append("\n"); + finalReport.append("\tVM Name: ").append(runtimeMxBean.getVmName()).append("\n"); + Map sys = runtimeMxBean.getSystemProperties(); + List sysData = new ArrayList<>(); + sys.keySet().forEach(key -> sysData.add(key + "=" + sys.get(key))); + finalReport.append("\tSystem Properties: ").append(Util.list2String(sysData)).append("\n"); + finalReport + .append("\tPlayers: ") + .append(Bukkit.getOnlinePlayers().size()) + .append("/") + .append(Bukkit.getMaxPlayers()) + .append("\n"); + finalReport.append("\tOnlineMode: ").append(Bukkit.getOnlineMode()).append("\n"); + finalReport.append("\tBukkitVersion: ").append(Bukkit.getVersion()).append("\n"); + finalReport.append("\tWorldContainer: ").append(Bukkit.getWorldContainer()).append("\n"); + List modules = new ArrayList<>(); + plugin.getIntegrationHelper().getIntegrations().forEach(m -> modules.add(m.getName())); + finalReport.append("\tLoaded Integrations: ").append(Util.list2String(modules)).append("\n"); + finalReport.append("================================================\n"); + finalReport.append("Worlds:\n"); + finalReport.append("\tTotal: ").append(Bukkit.getWorlds().size()).append("\n"); + for (World world : Bukkit.getWorlds()) { + finalReport.append("\t*********************************\n"); + finalReport.append("\t\tName: ").append(world.getName()).append("\n"); + finalReport.append("\t\tEnvironment: ").append(world.getEnvironment().name()).append("\n"); + finalReport.append("\t\tLoaded Chunks: ").append(world.getLoadedChunks().length).append("\n"); + finalReport.append("\t\tPlayer In World: ").append(world.getPlayers().size()).append("\n"); + finalReport + .append("\t\tShops In World: ") + .append(Util.getShopsInWorld(world.getName())) + .append("\n"); + } + finalReport.append("\t*********************************\n"); // Add a line after last world + finalReport.append("================================================\n"); + finalReport.append("Plugins:\n"); + finalReport + .append("\tTotal: ") + .append(Bukkit.getPluginManager().getPlugins().length) + .append("\n"); + for (Plugin bplugin : Bukkit.getPluginManager().getPlugins()) { + finalReport + .append("\t") + .append(bplugin.getName()) + .append("@") + .append(bplugin.isEnabled() ? "Enabled" : "Disabled") + .append("#") + .append(bplugin.getDescription().getVersion()) + .append("\n"); + } + finalReport.append("================================================\n"); + finalReport.append("Internal Data:\n"); + finalReport.append("Caching Pool Enabled: ").append(plugin.getShopCache() != null).append("\n"); + if (plugin.getShopCache() != null) { + finalReport.append("Caching Contents: ").append(plugin.getShopCache().getCachingSize()).append("\n"); + } + finalReport.append("================================================\n"); + finalReport.append("Configurations:\n"); + try { + finalReport.append("\t*********************************\n"); + finalReport.append("\tconfig.yml:\n"); + finalReport + .append("\t\t\n") + .append( + new String( + Objects.requireNonNull( + Util.inputStream2ByteArray(plugin.getDataFolder() + "/config.yml")), + StandardCharsets.UTF_8)) + .append("\n"); + finalReport.append("\t*********************************\n"); + finalReport.append("\tmessages.json:\n"); + finalReport + .append("\t\t\n") + .append( + new String( + Objects.requireNonNull( + Util.inputStream2ByteArray(plugin.getDataFolder() + "/messages.json")), + StandardCharsets.UTF_8)) + .append("\n"); + finalReport.append("\t*********************************\n"); + finalReport.append("\t*********************************\n"); + finalReport.append("\titemi18n.yml:\n"); + finalReport + .append("\t\t\n") + .append( + new String( + Objects.requireNonNull( + Util.inputStream2ByteArray( + new File(plugin.getDataFolder(), "itemi18n.yml").getPath())), + StandardCharsets.UTF_8)) + .append("\n"); + finalReport.append("\t*********************************\n"); + finalReport.append("\t*********************************\n"); + finalReport.append("\tenchi18n.yml:\n"); + finalReport + .append("\t\t\n") + .append( + new String( + Objects.requireNonNull( + Util.inputStream2ByteArray( + new File(plugin.getDataFolder(), "enchi18n.yml").getPath())), + StandardCharsets.UTF_8)) + .append("\n"); + finalReport.append("\t*********************************\n"); + finalReport.append("\t*********************************\n"); + finalReport.append("\tpotioni18n.yml:\n"); + finalReport + .append("\t\t\n") + .append( + new String( + Objects.requireNonNull( + Util.inputStream2ByteArray( + new File(plugin.getDataFolder(), "potioni18n.yml").getPath())), + StandardCharsets.UTF_8)) + .append("\n"); + finalReport.append("\t*********************************\n"); + finalReport.append("\t*********************************\n"); + finalReport.append("\tInternal Debug Log:\n"); + finalReport + .append("\t\t\n") + .append(Util.list2String(Util.getDebugLogs()).replaceAll(",", "\n")) + .append("\n"); + finalReport.append("\t*********************************\n"); + // try { + // finalReport.append("\t*********************************\n"); + // finalReport.append("\tlatest.log:\n"); + // finalReport.append("\t\t\n").append(new String(Objects.requireNonNull(Util + // .inputStream2ByteArray(new File(new File(".", "logs"), + // "latest.log").getPath())), StandardCharsets.UTF_8)).append("\n"); + // finalReport.append("\t*********************************\n"); + // } catch (Throwable th) { + // finalReport.append("\t*********************************\n"); + // finalReport.append("\tlatest.log:\n"); + // finalReport.append("\t\t\n").append("Read failed.").append("\n"); + // finalReport.append("\t*********************************\n"); + // } + try { + finalReport.append("\t*********************************\n"); + finalReport.append("\tbukkit.yml:\n"); + finalReport + .append("\t\t\n") + .append( + new String( + Objects.requireNonNull( + Util.inputStream2ByteArray( + new File(new File("."), "bukkit.yml").getPath())), + StandardCharsets.UTF_8)) + .append("\n"); + finalReport.append("\t*********************************\n"); + } catch (Throwable th) { + finalReport.append("\t*********************************\n"); + finalReport.append("\tbukkit.yml:\n"); + finalReport.append("\t\t\n").append("Read failed.").append("\n"); + finalReport.append("\t*********************************\n"); + } + try { + finalReport.append("\t*********************************\n"); + finalReport.append("\tspigot.yml:\n"); + finalReport + .append("\t\t\n") + .append( + new String( + Objects.requireNonNull( + Util.inputStream2ByteArray( + new File(new File("."), "spigot.yml").getPath())), + StandardCharsets.UTF_8)) + .append("\n"); + finalReport.append("\t*********************************\n"); + } catch (Throwable th) { + finalReport.append("\t*********************************\n"); + finalReport.append("\tspigot.yml:\n"); + finalReport.append("\t\t\n").append("Read failed.").append("\n"); + finalReport.append("\t*********************************\n"); + } + try { + finalReport.append("\t*********************************\n"); + finalReport.append("\tpaper.yml:\n"); + finalReport + .append("\t\t\n") + .append( + new String( + Objects.requireNonNull( + Util.inputStream2ByteArray(new File(new File("."), "paper.yml").getPath())), + StandardCharsets.UTF_8)) + .append("\n"); + finalReport.append("\t*********************************\n"); + } catch (Throwable th) { + finalReport.append("\t*********************************\n"); + finalReport.append("\tpaper.yml:\n"); + finalReport.append("\t\t\n").append("Read failed.").append("\n"); + finalReport.append("\t*********************************\n"); + } + } catch (Throwable th) { + finalReport.append("\tFailed to get data\n"); + } + finalReport.append("================================================\n"); + finalReport.append("Shops in DB:\n"); + plugin + .getShopLoader() + .getOriginShopsInDatabase() + .forEach( + (shopDatabaseInfoOrigin -> + finalReport.append("\t").append(shopDatabaseInfoOrigin).append("\n"))); + finalReport + .append("Total: ") + .append(plugin.getShopLoader().getOriginShopsInDatabase().size()) + .append("\n"); + finalReport.append("================================================\n"); + finalReport.append("Shops in Mem:\n"); + plugin + .getShopLoader() + .getShopsInDatabase() + .forEach((shop -> finalReport.append(shop).append("\n"))); + finalReport + .append("Total: ") + .append(plugin.getShopLoader().getShopsInDatabase().size()) + .append("\n"); + finalReport.append("================================================\n"); + + // Process the data to protect passwords. + String report = finalReport.toString(); + try { + ConfigurationSection configurationSection = + plugin.getConfig().getConfigurationSection("database"); + report = + report.replaceAll( + Objects.requireNonNull( + Objects.requireNonNull(configurationSection).getString("user")), + "[PROTECTED]"); + report = + report.replaceAll( + Objects.requireNonNull(configurationSection.getString("password")), "[PROTECTED]"); + report = + report.replaceAll( + Objects.requireNonNull(configurationSection.getString("host")), "[PROTECTED]"); + report = + report.replaceAll( + Objects.requireNonNull(configurationSection.getString("port")), "[PROTECTED]"); + report = + report.replaceAll( + Objects.requireNonNull(configurationSection.getString("database")), "[PROTECTED]"); + } catch (Throwable tg) { + // Ignore + } + return report; + } + + @Nullable + public String paste(@NotNull String content) { + PasteInterface paster; + try { + // EngineHub Pastebin + paster = new EngineHubPaster(); + return paster.pasteTheText(content); + } catch (Exception ignore) { + } + try { + // Ubuntu Pastebin + paster = new UbuntuPaster(); + return paster.pasteTheText(content); + } catch (Exception ignore) { + } + return null; + } + + + @Nullable + public String paste(@NotNull String content, int type) { + PasteInterface paster; + if (type == 0) { + try { + // EngineHub Pastebin + paster = new EngineHubPaster(); + return paster.pasteTheText(content); + } catch (Exception ignore) { + } + } else { + try { + // Ubuntu Pastebin + paster = new UbuntuPaster(); + return paster.pasteTheText(content); + } catch (Exception ignore) { + } + } + return null; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/PasteInterface.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/PasteInterface.java new file mode 100644 index 0000000..fb1d94e --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/PasteInterface.java @@ -0,0 +1,27 @@ +/* + * This file is a part of project QuickShop, the name is PasteInterface.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util.paste; + +import org.jetbrains.annotations.NotNull; + +public interface PasteInterface { + String pasteTheText(@NotNull String text) throws Exception; + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/UbuntuPaster.java b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/UbuntuPaster.java new file mode 100644 index 0000000..d8756fe --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/java/org/abc/A/util/paste/UbuntuPaster.java @@ -0,0 +1,71 @@ +/* + * This file is a part of project QuickShop, the name is UbuntuPaster.java + * Copyright (C) Ghost_chu + * Copyright (C) Bukkit Commons Studio and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package org.abc.A.util.paste; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import org.jetbrains.annotations.NotNull; +import org.abc.A.util.Util; + +public class UbuntuPaster implements PasteInterface { + /** + * Paste a text to paste.ubuntu.com + * + * @param text The text you want paste. + * @return Target paste URL. + * @throws Exception the throws + */ + @NotNull + public String pasteTheText(@NotNull String text) throws Exception { + URL url = new URL("https://paste.ubuntu.com"); + URLConnection conn = url.openConnection(); + conn.setRequestProperty("accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty( + "user-agent", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"); + conn.setDoOutput(true); + conn.setDoInput(true); + conn.setConnectTimeout(50000); + conn.setReadTimeout(100000); + PrintWriter out = new PrintWriter(conn.getOutputStream()); + // poster=aaaaaaa&syntax=text&expiration=&content=%21%40 + String builder = + "poster=" + + "QuickShop Paster" + + "&syntax=text" + + "&expiration=week" + + "&content=" + + URLEncoder.encode(text, "UTF-8"); + out.print(builder); + out.flush(); // Drop + BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); + Util.debugLog("Request Completed: " + conn.getURL()); + String link = conn.getURL().toString(); + in.close(); + out.close(); + return link; + } + +} diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/config.yml b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/config.yml new file mode 100644 index 0000000..5071a37 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/config.yml @@ -0,0 +1,509 @@ +#This is example config, don't direct modify this file, all changes will revert when you reload the plugin. + +#Do not touch if you not clear know about this +config-version: 95 + +#Select the language you want to use, (e.g de), use only supported language codes from the list below. +#If you use a not exist/not support language, plugin will move to use en_US to keep everything working. +#After you set the new language, you need to delete `messages.yml` to let plugin regen it with your desired language file. + +#Available languages: +#en +#de +#en-US +#es-419 +#fr +#ja +#ko +#pl +#ru +#zh-CN +#zh-TW + +language: en + +#After you setup this, quickshop will download items/blocks/enchs and potions translation from MOJANGAPI +#You can find supported language in your Minecraft Client Languages menu, fill this with the language Code. +#E.g [English (en-US)] The Language Code is en-US +game-language: default + +#This enables developer mode, Do not touch this if you not know what it does +dev-mode: false + +#Tax amount (decimal) - Eg, P1 buys $50 worth of stuff from P2. Therefore, P1 loses $50, P2 gains $(1-0.05)*50, and tax-account gains $(0.05)*50. +tax: 0.05 + +#The fake player where money from taxing people goes to +tax-account: tax + +#Whether or not to show taxes paid when selling to a shop +show-tax: false + +#Whether or not to respect item flag (e.g. hide the enchantment info when item have HIDE_ENCHANTS flag) +respect-item-flag: true + +#Should we log transactions/creations to Bukkit\Plugins\QuickShop\qs.log? +log-actions: true + +#For item-item based economies that don't use virtual coins. +whole-number-prices-only: false + +#Force bukkit chat handler (https://github.com/KaiKikuchi/QuickShop/issues/10) +force-bukkit-chat-handler: false + +#Disallow QuickShop-Reremake to send metrics data to bStats. +disabled-metrics: false + +#Should QS be allowed to check for updates on SpigotMC.org? +updater: false + +#Should QS be allowed to auto report errors to the author? +auto-report-errors: true + +#Should QS use OfflinePlayer list for TabComplete? +#This might give players a better experience, but may cause lag due to searching what can be a long list. +#false = Only use the OnlinePlayer list, true = A list of all players that have ever joined your server before. +include-offlineplayer-list: false + +#What economy provider you want let QuickShop use? +#0=Vault +#1=Reserve +#2=Vault+Command mixed +#DO NOT TOUCH THIS IF YOU DIDN'T KNOW WHAT WILL HAPPEN. ASK FOR SUPPORT BEFORE TOUCH THIS! +#DO NOT TOUCH THIS IF YOU DIDN'T KNOW WHAT WILL HAPPEN. ASK FOR SUPPORT BEFORE TOUCH THIS! +#DO NOT TOUCH THIS IF YOU DIDN'T KNOW WHAT WILL HAPPEN. ASK FOR SUPPORT BEFORE TOUCH THIS! +#DO NOT TOUCH THIS IF YOU DIDN'T KNOW WHAT WILL HAPPEN. ASK FOR SUPPORT BEFORE TOUCH THIS! +#DO NOT TOUCH THIS IF YOU DIDN'T KNOW WHAT WILL HAPPEN. ASK FOR SUPPORT BEFORE TOUCH THIS! +economy-type: 0 + +#The decimal format the double output, includes player money output +#Default is #,###.## +# whether to use decimal format output. +use-decimal-format: false + +decimal-format: "#,###.##" + +#Allow plugin send alert when something trying make a displayItem exploit +send-display-item-protection-alert: false + +#Allow plugin send alert when something trying steal shop +send-shop-protection-alert: false + +#Still WIP +server-platform: 0 + +#BETA=Use caching for shop finding to optimize performance if possible +use-caching: false + +#MySQL database settings. +database: + # false = use local SQLite database, true = use local/remote MySQL database. + mysql: false + host: localhost + port: 3306 + database: quickshop + user: root + password: passwd + # Set prefix to "none" to remove prefix + prefix: none + usessl: false + #Whether to use async queue? + queue: true + #How long between each commit when using queue? (seconds) + queue-commit-interval: 2 + # Auto set table encoding to utf8mb4 (beta) + auto-fix-encoding-issue-in-database: false + +#Limits the number of shops a person can create and own at a single time. +limits: + #Disable these if you're not using them! If this is false, the rest of this section is ignored + use: false + + #The default number of shops players can make + default: 10 + + #Use old algorithm to calc unlimited shops into limits. + old-algorithm: false + + #Players with these permissions can create these amounts of shops. + ranks: + #Anyone with 'quickshop.vip' permissions, can create 20 shops instead of 10. + quickshop.vip: 20 #Players with quickshop.vip can make 20 shops. + +#A list of block (materials) which can be used to create shops. +#By default, chests are added to this list. +#This will only work for blocks which implement InventoryHolder +#in other words, no enderchest shops, no shops on dirt blocks, etc. +#May cause unexpected behavior with some blocks... Eg don't make a +#shop on a hopper (It sucks the display item in) and furnace shops +#allow players to put whatever item they want in all 3 slots and +#dispenser shops aren't protected from redstone... Etc. +shop-blocks: + - CHEST + - TRAPPED_CHEST + - ENDER_CHEST +shop: + #Cost to make a shop + cost: 10 + #Should we refund the player when their shops are deleted/removed/broken? + refund: false + + #Should we disable trading for creative mode? + disable-creative-mode-trading: false + #Should we disable super tool?(It's a tool which allow you break shop in creative mode by gold axe) + disable-super-tool: false + #Should we allow the owner of shop break the sign (for sign replacement, but may cause sign dupe when auto-sign is true)? + allow-owner-break-shop-sign: false + + #Is there a fee for changing prices on a shop (Help deter endless undercutting) + price-change-requires-fee: true + #If price changes require a fee, how much is the fee + fee-for-price-change: 50 + + #Should we try and lock their shops from other players, so people can't steal from them? + lock: true + + #Should we require players be sneaking to create and use shops? + sneak-to-create: false + sneak-to-trade: false + sneak-to-control: false + + #Should we automatically create the sign for the chest? + auto-sign: true + + #Should we pay/take money to/from unlimited shops owner? + pay-unlimited-shop-owners: false + + #Should we place display items on the chests? This may cause duped items, especially for modded servers. + display-items: true + + #The plugin will check if the display item is in a valid position every specified amount of ticks. 0 to disable. + display-items-check-ticks: 6000 + + #The display type you want use. + #0=Normal Dropped Item, 1=ArmorStand, 2=Virtual Item(ProtocolLib needed, fallback to normal dropped item if ProtocoLib not installed) + display-type: 2 + + #Allow quickshop auto despawn-spawn the display when no-player or player close the shop. + display-auto-despawn: false + + #When range region no players, the display will despawn. + display-despawn-range: 20 + + #How long ticks we should check the shops once to decide despawn/spawn display? + display-check-time: 40 + + #Use enhance display protect + enchance-display-protect: false + + #Use enhance shop protect + enchance-shop-protect: false + + #When someone uses /qs find , how far should we search in blocks? + #This command lets users shop quickly without wasting time searching + #Settings > 100 WILL cause lag. Don't do it, or don't cry when your server lags. + find-distance: 45 + + #If vault doesn't return a coins symbol, QuickShop will use this symbol to replace it. + alternate-currency-symbol: '$' + + #It should fix Vault or an economy plugin that is not correctly processing the price and returns a "0" result problem. + #If you turn on this option, plugin will force use "alternate-currency-symbol" option. + disable-vault-format: false + + #Ignore trade messages if the shop is unlimited + ignore-unlimited-shop-messages: false + + #Allow auto fetching player shops, if you disable this, players need to use /qs fetchmessage to fetch the shops history messages. (Disabling it may cause database issues.) + auto-fetch-shop-messages: true + + #Ignore cancel chat event, can improve compatibility with other chat plugin in some cases. + ignore-cancel-chat-event: false + + #Allow shops to be created in a place where a sign cannot placed + #(e.g There is blocks on all sides of the shop / The player doesn't have permission to put down a sign at that location) + allow-shop-without-space-for-sign: false + + #The minimum price for shop, This will not affect existing shops, default is 0.01. + minimum-price: 0.01 + + #The maximum price for shop, This will not affect existing shops, set it to -1 to disable it. + maximum-price: -1 + + #Setting per item price restriction + #Format: ;; + #e.g: + #price-restriction: + # - DIAMOND;100;200 + price-restriction: [] + + #The number of digits after decimal, set it to -1 to disable it + maximum-digits-in-price: -1 + + #if shop is adminshop, and player has permission to change shop owner, Whether in controll panel, print the owner's uuid? + show-owner-uuid-in-controlpanel-if-op: false + + #The wall sign material. + #In 1.13 and legacy versions, only WALL_SIGN is available. + # + #For 1.14, you can use these: + #ACACIA_WALL_SIGN + #BIRCH_WALL_SIGN + #DARK_OAK_WALL_SIGN + #JUNGLE_WALL_SIGN + #OAK_WALL_SIGN + #SPRUCE_WALL_SIGN + sign-material: OAK_WALL_SIGN + + #The worlds name for you didn't want create new shop. + blacklist-world: + - disabled_world_name + + #The lores keyword on you didn't want allow sell item. + #Won't effect already created shops. + blacklist-lores: + - "SoulBound" + + #Protection check + protection-checking: true + + #How many shops can be checked in once? (Container exists check) + max-shops-checks-in-once: 100 + + #Add display name to the spawned DisplayItem entity? + display-item-use-name: false + + #Update the signs when Hopper or somethings trigged InventoryMoveItemEvent. + #Disable it if you feel it damage your server performance. + update-sign-when-inventory-moving: true + + #Allow player loan (Require economy plugin support) + allow-economy-loan: false + + #The word to trade all items in player inventory + word-for-trade-all-items: "all" + + #Allow player to create 0$ shop. + #THIS MAY BROKEN SOMETHING + allow-free-shop: false + + #Use fast algorithm for ShopManager#getShopIncludeAttached, it should improve HUGE performance on it. + use-fast-shop-search-algorithm: true + + #The shop ongoing fee, if a shop's owner had no enough money, shop will auto-remove. + ongoing-fee: + enable: false + #How often we will take the ongoing-fee from the players? + ticks: 42000 + #How many money we take from the shop's owner every times? + cost-per-shop: 2 + #Should we ignore the unlimited shop? + ignore-unlimited: true + #Allow QuickShop use hack util to force load shops from higher Minecraft. + #WARNING: It may destory your server data and QuickShop shops, backup before enable it! + force-load-downgrade-items: + enable: false + #WorkMode + #0=Call Bukkit try update the ItemStack + #1=Call Bukkit direct load the ItemStack + method: 0 + #If a block/entity trigged protection, quickshop should break/kill it? + remove-protection-trigger: true +#List of items that can't be sold in shops. Anyone with quickshop.bypass. can bypass it +blacklist: + - Bedrock + +lockette: + #Fix Quickshop not canceling a break lock sign event (Making it impossible to break a locked chest)\ + enable: true + private: "[Private]" + more_users: "[More Users]" +# Enable or disable plugin support. +plugin: + #If you have Multiverse-Core, QSRR will try load world when shop's world don't exist and will throw an exception and auto repair the shops. + Multiverse-Core: true + #If you have OpenInv, QSRR will enable EnderChest feature. + OpenInv: true + #If you have PlaceHolderAPI, QuickShop will use PlaceHolderAPI to process all messages. + PlaceHolderAPI: true + #Should QuickShop support for plugin BlockHub to use BlockHub to check region access for players? + BlockHub: + enable: true + #Only use BlockHub for permission checker? + only: false +effect: + sound: + ontabcomplete: true + oncommand: true + onclick: true +#Item matcher, don't touch it if you didn't know how to use it. +matcher: + # Matcher type + #0= QuickShop item matcher with configurable options below. + #1= Bukkit item matcher, can be more accurate. + work-type: 0 + #For Item + item: + #Plugin should check the item damage? + damage: true + #Plugin should check the item repair cost? + repaircost: false + #Plugin should check the item display name? + displayname: true + #Plugin should check the item lores? + lores: true + #Plugin should check the item enchs? + enchs: true + #Plugin should check the item potions? + potions: true + #Plugin should check the item attributes? + attributes: true + #Plugin should check the item itemflags? + itemflags: true + #Plugin should check the item custommodeldata? + custommodeldata: true + #Plugin should check the item bookmetas? + books: true + #Plugin should check the banner meta? + banner: true + #Plugin should check the skull meta? + skull: true + #Plugin should check the firework meta? + firework: true + #Plugin should check the map meta? + map: true + #Plugin should check the leather armor meta? + leatherArmor: true + #Plugin should check the fishBucket meta? + fishBucket: true + #Plugin should check the suspiciousStew meta? + suspiciousStew: true + #Plugin should check the shulkerBox contents? + shulkerBox: true +cachingpool: + # Did you want use caching pool? + # Only use it when you see some method eat too many long time, because may cause actions more slowly if you server too small. + enable: false + # How many size for caching pool? + # When objects more than this number, it will removed some old object. + maxsize: 100000000 +mixedeconomy: + deposit: "eco give {0} {1}" + withdraw: "eco take {0} {1}" +#Integration is under BETA stage, please report any bugs to our Issue Tracker. +integration: + #Towny Integration Component + towny: + enable: false + #Player if want create a shop, player must pass which checks? + #You can use multi checks in same time. + #Priority: UP to DOWN. + # + #Avaliable field: + #OWN = Player must create the shop on their plot. + #MODIFY = Player must have ability to build at the target plot. + #SHOPTYPE = Player must create the shop on SHOP type plot. + create: + - SHOPTYPE + - MODIFY + #Player if want trade with the shop, player must pass which checks? + #You can use multi checks in same time. + #Priority: UP to DOWN. + # + #Avaliable field: + #OWN = Player must create the shop on their plot. + #MODIFY = Player must have ability to build at the target plot. + #SHOPTYPE = Player must create the shop on SHOP type plot. + trade: [] + #WorldGuard Integration Component + worldguard: + enable: false + #Player if want create a shop, player must pass which checks? + #You can use multi checks in same time. + #Priority: UP to DOWN + # + #Avaliable field: + #FLAG = Region must set quickshop-create flag available for players. + #BUILD = Player must have ability to build at the target region. + #CHEST_ACCESS = Player must can access chest. + #INTERACT = Player must have ability to interact in the target region. + create: + - FLAG + - CHEST_ACCESS + #Player if want create a shop, player must pass which checks? + #You can use multi checks in same time. + #Priority: UP to DOWN + # + #Avaliable field: + #FLAG = Region must set quickshop-trade flag available for players. + #BUILD = Player must have ability to build at the target region. + #CHEST_ACCESS = Player must can access chest. + #INTERACT = Player must have ability to interact in the target region. + trade: [] + plotsquared: + enable: false + #Player if want create a shop, player must have quickshop-create flag + #Player if want trade a shop, player must have quickshop-trade flag + residence: + enable: false + #Player if want create a shop, player must pass which checks? + #You can use multi checks in same time. + #Priority: UP to DOWN + # + #Avaliable field: + #FLAG = Region must set quickshop.create flag available for players. + # = Other avaliable flags in Residence plugin or Residence addons registered flags. + create: + - FLAG + - interact + - use + #Player if want trade a shop, player must pass which checks? + #You can use multi checks in same time. + #Priority: UP to DOWN + # + #Avaliable field: + #FLAG = Region must set quickshop.create flag available for players. + # = Other avaliable flags in Residence plugin or Residence addons registered flags. + trade: [] + factions: + enable: false + #Player if want create a shop, player must pass which checks? + create: + #Faction require the status must match with under: + require: + open: false + normal: true + wilderness: false + peaceful: true + permanent: false + safezone: false + own: false + warzone: false + #Player must have flags in the faction: + flags: + - CONTAINER + - ECONOMY + #Faction require the status must match with under? + trade: + #Faction require: + require: + open: false + normal: true + wilderness: false + peaceful: false + permanent: false + safezone: false + own: false + warzone: false + #Player must have flags in the faction: + flags: [] +#the protection that shop should check +protect: + explode: true + hopper: true + + + + + + diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/enchi18n.yml b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/enchi18n.yml new file mode 100644 index 0000000..e69de29 diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/itemi18n.yml b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/itemi18n.yml new file mode 100644 index 0000000..e69de29 diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang-original/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang-original/messages.json new file mode 100644 index 0000000..f9886aa --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang-original/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a\u2714", + "failed": "&c\u2718" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/af-ZA/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/af-ZA/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/af-ZA/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ar-SA/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ar-SA/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ar-SA/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ca-ES/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ca-ES/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ca-ES/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/cs-CZ/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/cs-CZ/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/cs-CZ/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/da-DK/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/da-DK/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/da-DK/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/de-DE/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/de-DE/messages.json new file mode 100644 index 0000000..c00c6b6 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/de-DE/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Übersetzer: Jason897, Andre_601", + "translation-version": "Unterstütze Version: Reremake", + "translation-contributors": "Unterstützer: Andre_601", + "translation-country": "Sprache: Deutsch (de_DE)", + "language-version": "31", + "not-looking-at-shop": "&cEs wurde kein Shop gefunden. Bitte schau auf einen Shop, um diese Aktion auszuführen.", + "no-anythings-in-your-hand": "&cEs befindet sich kein Gegenstand in deiner Hand.", + "no-permission": "&cDu hast keine Berechtigung, dies zu tun.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cDu kannst keinen Doppeltruhen-Shop nicht erstellen.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cDies ist bereits ein Shop.", + "chest-was-removed": "&cDie Truhe wurde entfernt.", + "price-too-cheap": "&cDer Preis muss höher als &e${0} sein", + "no-price-change": "&cDer Preis würde sich nicht ändern!", + "you-cant-afford-a-new-shop": "&cDu benötigst {0}, um einen neuen Shop zu erstellen.", + "player-bought-from-your-store-tax": "&c{0} hat {1} {2} in deinem Shop eingekauft. Dabei wurden {3} Steuern fällig.", + "you-cant-afford-to-change-price": "&cEs kostet {0}, um den Preis zu verändern.", + "success-created-shop": "&aShop erstellt.", + "success-removed-shop": "&aShop entfernt.", + "shops-arent-locked": "&cVergiss nicht, dass Shops NICHT gegen Diebstahl gesichert sind! Wenn du Diebe aufhalten willst, musst du sie mit LWC, Lockette, o.ä. schützen!", + "shop-creation-cancelled": "&cShop erstellung abgebrochen.", + "shop-purchase-cancelled": "&cKauf abgebrochen.", + "shop-stock-too-low": "&cDer Shop verfügt nur noch über {0} {1}", + "you-cant-afford-to-buy": "&cDies würde {0} kosten, du hast aber lediglich {1}", + "negative-amount": "&cTrottel. Du kannst keine negative Menge handeln", + "not-a-number": "&cEs dürfen nur Zahlen eingegeben werden, aber du hast {0} eingegeben", + "not-a-integer": "&cEs dürfen nur ganze Zahlen eingegeben werden, aber du hast {0} eingegeben", + "player-bought-from-your-store": "&c{0} hat {1} {2} in deinem Shop eingekauft.", + "shop-out-of-stock": "&5Dein Shop bei den Koordinaten {0}, {1}, {2}, verfügt über keine {3} mehr", + "shop-has-no-space": "&cDer Shop hat nur noch Platz für {0} weitere {1}.", + "you-dont-have-that-many-items": "&cDu hast nur {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cDies würde {0} kosten, aber der Besitzer hat nur {1}", + "player-sold-to-your-store": "&a{0} hat {1} {2} bei deinem Shop verkauft.", + "shop-out-of-space": "&5Dein Shop bei den Koordinaten {0}, {1}, {2}, ist jetzt voll.", + "fee-charged-for-price-change": "&aDu hast &c{0}&a bezahlt, um den Preis zu ändern.", + "price-is-now": "&aDer neue Preis ist nun &e{0}", + "thats-not-a-number": "&cUngültige Zahl", + "no-price-given": "&cBitte gebe einen gültigen Preis ein.", + "average-price-nearby": "&aDer durchschnittliche Preis in der Umgebung ist &e{0}", + "shop-has-changed": "&cDer Shop, den du gerade benutzt wolltest, wurde verändert seit dem du drauf geklickt hast!", + "shop-not-exist": "&cDieser Shop existiert nicht.", + "nearby-shop-this-way": "&aDieser Shop ist {0} Blöcke von dir entfernt.", + "no-nearby-shop": "&cIn der Umgebung befindet sich kein Shop mit {0}.", + "buying-more-than-selling": "&cWARNUNG: Du kaufst diesen Gegenstand für mehr Geld als du ihn verkaufst!", + "not-enough-space": "&cDu hast nur noch Platz für {0} mehr davon!", + "refill-success": "&aDer Shop wurde erfolgreich aufgefüllt.", + "empty-success": "&aDer Shop wurde erfolgreich geleert.", + "admin-shop": "AdminShop", + "unknown-owner": "Unbekannt", + "owner-bypass-check": "&eAlle Überprüfungen wurden ignoriert, der Handel war erfolgreich! (Du bist der Besitzer des Shops)", + "reached-maximum-can-create": "&cDu hast bereits das Maximum von {0}\/{1} Shops erreicht!", + "restricted-prices": "&cDer Pres von {0} wurde eingeschränkt. Dieser muss mindestens {1} und darf maximal {2} betragen.", + "no-enough-money-to-keep-shops": "&cDu hattest nicht genug Geld, um deine Shops zu behalten! Daher wurden all deine Shops entfernt...", + "nothing-to-flush": "&aEs gibt keine neuen Nachrichten zu deinem Shop.", + "break-shop-use-supertool": "&eDu kannst diesen Shop mithilfe des SuperTools zerstören.", + "failed-to-put-sign": "&cEs gibt keinen Platz um den Shop, um das Informationsschild zu platzieren.", + "failed-to-paste": "&cDer Upload zu Pastebin war nicht möglich. Bitte überprüfe deine Internetverbindung und versuche es erneut. (Siehe Konsole für Details)", + "warn-to-paste": "&eSammelt Daten und lädt diese anschließend auf Pastebin hoch, dies kann eine Weile dauern. &c&lAchtung&c: Die hochgeladenen Daten werden dort eine Woche lang gespeichert. Die Daten können möglicherweise Konfigurationseinstellungen oder andere sensitive Daten enthalten. Stelle sicher diese nur Teammitgliedern und Entwicklern zu Verfügung zu stellen, denen du &lvertraust.", + "price-too-high": "&cDer Preis ist zu hoch! Du kannst keinen Shop erstellen mit einem Preis über {0}.", + "you-cant-create-shop-in-there": "&cDu bist nicht berechtigt an diesem Ort ein Shop zu erstellen.", + "unknown-player": "&cDieser Spieler existiert nicht. Bitte überprüfe, ob der Name korrekt geschrieben wurde.", + "shop-staff-cleared": "&aEs wurden erfolgreich alle Mitarbeiter deines Shops entfernt.", + "shop-staff-added": "&a{0} erfolgreich als Shop-Mitarbeiter hinzugefügt.", + "shop-staff-deleted": "&a{0} erfolgreich als Shop-Mitarbeiter entfernt.", + "no-permission-build": "&cDu kannst hier keinen Shop erstellen.", + "success-change-owner-to-server": "&aDer Shop wurde erfolgreich dem Server überschrieben.", + "flush-finished": "&aDie Nachrichten wurden erfolgreich abgerufen.", + "purchase-failed": "&cKauf fehlgeschlagen: Interner Fehler, bitte kontaktiere einen Serveradministrator.", + "no-pending-action": "&cDu hast keine ausstehende Aktion", + "permission-denied-3rd-party": "&cZugriff verweigert: Drittanbieter-Plugin [{0}].", + "menu": { + "successful-purchase": "&aFolgendes wurde erfolgreich gekauft:", + "successfully-sold": "&aFolgendes wurde erfolgreich verkauft:", + "item-name-and-price": "&e{0} {1} &afür &e{2}", + "sell-tax": "&aDu hast &e{0} &aan Steuern zahlen müssen.", + "sell-tax-self": "&aDu bist der Besitzer des Shops, also fallen für dich keine Steuern an.", + "enchants": "&5Verzauberungen", + "stored-enchants": "&5Verfügt über Verzauberungen", + "shop-information": "&aShop Informationen:", + "owner": "&aBesitzer: {0}", + "item": "&aGegenstand: &e{0}", + "preview": "&b[Gegenstandsvorschau]", + "space": "&aKapazität: &e{0}", + "stock": "&aLagerbestand: &e{0}", + "price-per": "&aPreis pro &e{0} &a- &e{1}", + "total-value-of-chest": "&aGesamtwert des Kiste: &e{0}", + "damage-percent-remaining": "&e{0}% &aÜbrig (Haltbarkeit).", + "this-shop-is-buying": "&aDieser Shop &dKAUFT&a Gegenstände an.", + "this-shop-is-selling": "&aDieser Shop &bVERKAUFT&a Gegenstände.", + "effects": "&aEffekte", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cUmgehe einen QuickShop schutz!", + "that-is-locked": "&cDieser Shop ist geschützt.", + "how-many-buy": "&aSchreibe in den Chat, wieviele du &bKAUFEN&a möchtest. Du kannst &e{0}&a Stück kaufen. Gib &ball&a ein um alle zu kaufen.", + "how-many-sell": "&aSchreibe in den Chat, wieviele du &dVERKAUFEN&a möchtest. Du hast noch &e{0}&a verfügbar. Gib &ball&a ein um alle zu verkaufen.", + "not-allowed-to-create": "&cDu kannst hier keinen Shop erstellen.", + "blacklisted-item": "&cDieser Gegenstand wurde vom Verkauf ausgeschlossen.", + "how-much-to-trade-for": "&aSchreibe jetzt den Preis für einen &e{0}&a in den Chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aDer Shop ist nun unlimitiert", + "limited": "&aDer Shop ist nun limitiert" + }, + "no-owner-given": "&cDieser Shop verfügt über keinen Besitzer. Benutze &a\/qs setowner &c um einen Besitzer festzulegen.", + "new-owner": "&aNeuer Besitzer: &e{0}", + "now-buying": "&e{0} &awerden jetzt &dANGEKAUFT", + "now-selling": "&e{0} &awerden jetzt &dVERKAUFT", + "cleaning": "&aShops ohne Lagerbestand werden jetzt entfernt...", + "reloading": "&aWird neu geladen...", + "cleaned": "&e{0}&a Shops wurden entfernt.", + "no-type-given": "&cVerwendung: \/qs find ", + "no-amount-given": "&cKeine Anzahl angegeben. Benutze &a\/qs refill &c", + "now-debuging": "&aDer Entwicklermodus wurde erfolgreich aktiviert. QuickShop lädt jetzt neu...", + "now-nolonger-debuging": "&aDer Entwicklermodus wurde erfolgreich deaktiviert. QuickShop lädt jetzt neu...", + "wrong-args": "&cParameter stimmen nicht überein. Siehe \/qs help für Hilfe", + "description": { + "title": "&aQuickShop Hilfe", + "unlimited": "&eMacht einen Shop unlimitiert", + "setowner": "&eÄndert den Besitzer des Shops", + "owner": "&eÄndert den Besitzer des Shops", + "buy": "&eÄndert einen Shop zu &dKAUF&e-Modus", + "sell": "&eÄndert einen Shop zu &bVERKAUF&e-Modus", + "price": "&eVerändert den Kauf-\/Verkaufspreis für den jeweiligen Shop", + "clean": "&eEntferne alle (geladenen) Shops ohne Lagerbestand", + "find": "&eErmittelt den nächsten Shop in der Umgebung mit dem gesuchten Gegenstand.", + "reload": "&eLädt die config.yml von QuickShop neu", + "refill": "&eFügt eine gegebene Anzahl an Gegenständen dem Shop hinzu.", + "empty": "&eEntferne den Lagerbestand von einem Shop", + "debug": "&eWechselt in den Entwicklermodus", + "create": "&eErstelle einen neuen Shop bei der angeschauten Kiste", + "fetchmessage": "&eZeigt alle ungelesene Nachrichten zum Shop an", + "info": "&eZeigt Statistiken zu QuickShop an", + "paste": "&eAutomatischer Upload der Daten zu Pastebin", + "staff": "&eVerwalte die Mitarbeiter deines Shops", + "remove": "&eEntfernt den Shop den du anschaust", + "amount": "&eZum eingeben einer Zahl, falls die Eingabe über den Chat nicht funktioniert", + "about": "&eZeigt die Informationen über den QuickShop", + "help": "&eZeigt die QuickShop-Hilfe", + "supercreate": "&eErstellt einen Shop der alle Schutzüberprüfungen umgeht" + } + }, + "signs": { + "selling": "Verkauft {0}", + "header": "&c{0}", + "buying": "Kauft {0}", + "item": "{0}", + "price": "{0} p. St.", + "unlimited": "Unlimitiert " + }, + "controlpanel": { + "setowner": "&aBesitzer: &b{0} &e[&d&lÄndern&e]", + "infomation": "&aShop Bedienpanel:", + "setowner-hover": "&eKlicke hier um den Besitzer zu wechseln.", + "unlimited": "&aUnlimitiert: {0} &e[&d&lÄndern&e]", + "unlimited-hover": "&eKlicke hier um umzuschalten, ob der Shop unlimitiert ist.", + "mode-selling": "&aShop-Modus: &bVerkaufen &e[&d&lÄndern&e]", + "mode-selling-hover": "&eKlicke hier um den Shop in den Ankaufmodus umzuschalten.", + "mode-buying": "&aShop-Modus: &bAnkaufen &e[&d&lÄndern&e]", + "mode-buying-hover": "&eKlicke hier um den Shop in den Verkaufmodus umzuschalten.", + "price": "&aPreis: &b{0} &e[&d&lÄndern&e]", + "price-hover": "&eKlicke hier um einen neuen Preis für den Shop festzulegen.", + "refill": "&aAuffüllen: Fülle die Gegenstände im Shop auf &e[&d&lOK&e]", + "refill-hover": "&eKlicke hier um den Shop aufzufüllen.", + "empty": "&aLeeren: Entfernt alle Gegenstände aus dem Shop &e[&d&lOK&e]", + "empty-hover": "&eKlicke hier um den Shop zu leeren.", + "remove": "&c&l[Shop entfernen]", + "remove-hover": "&eKlicke um diesen Shop zu entfernen.", + "commands": { + "setowner": "\/qs setowner [Spieler]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [Neuer Preis]", + "refill": "\/qs refill [Anzahl]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[Preis]", + "range": "[Reichweite]", + "amount": "[Anzahl]" + }, + "updatenotify": { + "buttontitle": "[Jetzt Aktualisieren]", + "onekeybuttontitle": "[Ein Klick Update]", + "list": [ + "{0} ist bereits veröffentlicht, du verwendest noch immer {1}!", + "Boom! Neuse update {0} kommt, Aktualisiere!", + "Überraschung! {0} ist erschienen, der Server ist aber noch auf {1}", + "Sieht so aus, als solltest du mal das Plugin aktualisieren, {0} ist verfügbar!", + "Ooops! {0} ist verfügbar, es wird aber noch {1} verwendet!", + "Ich schwör, QS wurde geupdated {0}, warum hast du noch nicht die neue Version?", + "Fehlerbehebu.. Sorry {0} ist verfügbar!", + "Err! Nein, dies ist kein Fehler, {0} ist verfügbar!", + "OMG! {0} ist erschienen! Warum verwendest du immer noch {1}?", + "Heutige Neuigkeit: Es gibt eine neue Version von QuickShop {0}!", + "Plugin K.I.A, du solltest zu {0} updaten!", + "Brand Neues Update {0}!", + "Kommandeur es gibt ein Update! {0} ist grade erschienen!", + "Schau mich an---{0} update, du bist noch auf {1}", + "Ahhhhhhh! Neues Update {0}! Update!", + "Was denkst du? {0} ist draußen! Update!" + ], + "remote-disable-warning": "&cDiese Version von QuickShop wird vom Remote-Server als deaktiviert markiert, das bedeutet, dass diese Version ein ernsthaftes Problem haben könnte. Details findest du auf unserer SpigotMC-Seite: {0}. Diese Warnung wird angezeigt und spammt deine Konsole zu, bis du eine andere, nicht deaktivierte Version verwendest, um diese zu ersetzen. Dies hat keine Auswirkungen auf den Server.", + "label": { + "unstable": "[Instabil]", + "stable": "[Stabil]", + "lts": "[LTS]", + "qualityverifyed": "[Qualität]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cDein Shop bei den Koordinaten {0} wurde entfernt, da du nicht genug Geld hattest um ihn zu behalten!", + "digits-reach-the-limit": "&cDu hast das Limit an Nachkommastellen für den Preis erreicht.", + "complete": "&aAbgeschlossen!", + "quickshop-gui-preview": "QuickShop GUI Vorschau Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/el-GR/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/el-GR/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/el-GR/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/en-US/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/en-US/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/en-US/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/es-ES/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/es-ES/messages.json new file mode 100644 index 0000000..7ccde87 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/es-ES/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "&c&lTraductores: &b&lGhost_chu, LoudCloud, DorianXYZ, Erduke21 y Ant4rez", + "translation-version": "&c&lVersión soportada: &b&lReremake", + "translation-contributors": "&c&lContribuyentes: &b&lTimtower, Netherfoam, KaiNoMood, Mgazul, LoudCloud, CKittycannon, ERDUKE21 y Ant4rez", + "translation-country": "&c&lZona de lenguaje: &b&lEspañol (es_LA)", + "language-version": "31", + "not-looking-at-shop": "&cNo se encontró ninguna QuickShop, debes estar mirando una.", + "no-anythings-in-your-hand": "&cNo hay nada en tu mano.", + "no-permission": "&cNo tienes permiso para hacer eso.", + "3rd-plugin-build-check-failed": "Algún complemento de terceros denegó las verificaciones de permisos, ¿tenía permiso incorporado allí?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cNo puedes crear tiendas de cofres dobles.", + "not-managed-shop": "&cNo eres el dueño o moderador de la tienda", + "shop-already-owned": "&cEso ya es una tienda.", + "chest-was-removed": "&cEl cofre ha sido removido.", + "price-too-cheap": "&cEl precio debe ser mayor a &e${0}", + "no-price-change": "&c¡Eso no va a alterar el precio!", + "you-cant-afford-a-new-shop": "&cCuesta {0} crear una tienda.", + "player-bought-from-your-store-tax": "&c{0} ha comprado {1} {2} en tu tienda, y has pagado {3} en impuestos.", + "you-cant-afford-to-change-price": "&cCuesta {0} para cambiar el precio en tu tienda.", + "success-created-shop": "&aTienda creada.", + "success-removed-shop": "&aLa tienda ha sido eliminada.", + "shops-arent-locked": "&c¡Recuerda, las tiendas NO ESTÁN PROTEGIDAS contra el robo! Si quieres detener a los ladrones, protege tu cofre con LWC, Lockette, BlockLocker, etc.", + "shop-creation-cancelled": "&cSe canceló la creación de la tienda.", + "shop-purchase-cancelled": "&cSe canceló la compra de la tienda.", + "shop-stock-too-low": "&cSólo queda {0} {1} en la tienda", + "you-cant-afford-to-buy": "&cEso cuesta {0}, pero sólo tienes {1}", + "negative-amount": "&cRayos, no se puede intercambiar cantidades negativas", + "not-a-number": "&cSolo puede haber números, pero tu ingresaste {0}", + "not-a-integer": "&cSolo puede haber un numero entero, pero tu ingresaste {0}", + "player-bought-from-your-store": "&c{0} compró {1} {2} de tu tienda.", + "shop-out-of-stock": "&5Tu tienda en {0}, {1}, {2}, se ha quedado sin {3}", + "shop-has-no-space": "&cLa tienda sólo tiene espacio para {0} más {1}.", + "you-dont-have-that-many-items": "&cSolo tienes {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cEso cuesta {0} pero el dueño solo tiene {1}", + "player-sold-to-your-store": "&a{0} vendido {1} {2} a su tienda.", + "shop-out-of-space": "&5Su tienda en {0}, {1}, {2}, ahora está llena.", + "fee-charged-for-price-change": "&aPagas &c{0}&a para cambiar el precio.", + "price-is-now": "&aEl nuevo precio de las tiendas es &e{0}.", + "thats-not-a-number": "&cNúmero inválido.", + "no-price-given": "&cPor favor ingresa un precio válido.", + "average-price-nearby": "&aPrecio promedio local: &e{0}", + "shop-has-changed": "&c¡La tienda que trataste de usar ha cambiado desde que la clickeaste!", + "shop-not-exist": "&cNo había una tienda.", + "nearby-shop-this-way": "&aLa tienda está a {0} bloques de ti.", + "no-nearby-shop": "&cNo hay tiendas de {0} cerca.", + "buying-more-than-selling": "&cATENCIÓN: ¡Estás comprando artículos por más de lo que los estás vendiendo!", + "not-enough-space": "&c¡Sólo tienes espacio para {0} más!", + "refill-success": "&aCorrectamente rellenado", + "empty-success": "&aCorrectamente vaciado", + "admin-shop": "Tienda Admin", + "unknown-owner": "Desconocido", + "owner-bypass-check": "&eOmitidas todas las pruebas, ¡intercambio correcto! (Tú eres el dueño de la tienda)", + "reached-maximum-can-create": "&c¡Ya tienes creadas un máximo de {0}\/{1} tiendas!", + "restricted-prices": "&cPrecios restringidos para {0}: min {1}, max {2}", + "no-enough-money-to-keep-shops": "&c¡No tienes suficiente dinero para mantener tus tiendas! Todas las tiendas han sido eliminadas...", + "nothing-to-flush": "&aNo tienes mensajes de tus tiendas.", + "break-shop-use-supertool": "&ePuedes romper la tienda usando la SuperTool.", + "failed-to-put-sign": "&cNo hay suficiente espacio alrededor de la tienda para poner el letrero informativo.", + "failed-to-paste": "&cNo se pudo subir la información a PasteBin. Comprueba tu conexión a internet e intenta de nuevo. (Revisa la consola para más detalles)", + "warn-to-paste": "&eReuniendo datos y subiéndolos a Pastebin, esto puede tardar un poco. &c&lAtención&c, Los datos serán públicos por una semana, pueden revelar la configuración de tu servidor así como otros datos privados, asegúrate de mandarla sólo al &lPersonal o desarrolladores&c de confianza.", + "price-too-high": "&c¡El precio de la tienda es demasiado alto! No puedes crear una si cuesta más de {0}", + "you-cant-create-shop-in-there": "&cNo tienes permiso para crear una tienda en este lugar.", + "unknown-player": "&cDicho jugador no existe, por favor revisa el nombre de usuario que escribiste.", + "shop-staff-cleared": "&aRetirado todo el personal de tu tienda correctamente.", + "shop-staff-added": "&aAgregado\/s {0} correctamente a tu personal.", + "shop-staff-deleted": "&aSe eliminaron exitosamente {0} del personal de su tienda.", + "no-permission-build": "&cNo puedes montar una tienda aquí.", + "success-change-owner-to-server": "&aEstablecido exitosamente el dueño de la tienda al Servidor.", + "flush-finished": "&aPurgó con éxito los mensajes.\n", + "purchase-failed": "&cFalló la compra: Error Interno, por favor contacte al administrador del servidor.", + "no-pending-action": "&cNo tienes ninguna acción pendiente", + "permission-denied-3rd-party": "&cPermiso denegado: complementos de terceros [{0}].", + "menu": { + "successful-purchase": "&aCompra exitosa:", + "successfully-sold": "&aVenta exitosa:", + "item-name-and-price": "&e{0} {1} &apor &e{2}", + "sell-tax": "&aPagaste &e{0} &aen impuestos.", + "sell-tax-self": "&aEsta tienda te pertenece, por lo que no pagas impuestos.", + "enchants": "&5Encantamientos", + "stored-enchants": "&5Encantamientos almacenados", + "shop-information": "&aDescripción de tienda:", + "owner": "&aPropietario: {0}", + "item": "&aArticulo: &e{0}", + "preview": "&b[Previsualizar]", + "space": "&aEspacio: &e{0}", + "stock": "&aAlmacenado &e{0}", + "price-per": "&aPrecio por &e{0} &a- &e{1}", + "total-value-of-chest": "&aValor total del cofre: &e{0}", + "damage-percent-remaining": "&e{0}% &aRestante.", + "this-shop-is-buying": "&aEsta tienda está &dCOMPRANDO&a artículos.", + "this-shop-is-selling": "&aEsta tienda está &dVENDIENDO&a artículos.", + "effects": "&aEfectos", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&c¡Omitiendo el bloqueo de una QuickShop!", + "that-is-locked": "&cLa tienda está bloqueada.", + "how-many-buy": "&aIngresa cuanto deseas &bCOMPRAR&a en el chat. Ingresa &ball&a para comprarlo todo.", + "how-many-sell": "&aIngresa cuanto deseas &bVENDER&a en el chat. Tienes &e{0}&a disponible. Ingresa &ball& para venderlo todo.", + "not-allowed-to-create": "&cNo puedes crear una tienda aquí.", + "blacklisted-item": "&cArtículo en lista negra. No puedes venderlo", + "how-much-to-trade-for": "&aIntroduce cuánto pides por un &e{0}&a en el chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aLa tienda ahora es ilimitada.", + "limited": "&aLa tienda ahora es limitada." + }, + "no-owner-given": "&cNo se especificó propietario. Usa &a\/qs setowner &c", + "new-owner": "&aNuevo dueño: &e{0}", + "now-buying": "&aAhora &dCOMPRANDO &e{0}", + "now-selling": "&aAhora &dVENDIENDO &e{0}", + "cleaning": "&aLimpiando tiendas sin existencias...", + "reloading": "&aRecargando...", + "cleaned": "&e{0}&a Tiendas han sido limpiadas", + "no-type-given": "&cUso: \/qs find ", + "no-amount-given": "&cNo se especificó cantidad. Usa &a\/qs refill &c", + "now-debuging": "&aCambio con éxito a modo desarrollador, Recargando QuickShop...", + "now-nolonger-debuging": "&aCambio con éxito a modo producción, Recargando QuickShop...", + "wrong-args": "&cLos parámetros no coinciden, usa \/qs help para revisar la ayuda", + "description": { + "title": "&aQuickShop Ayuda", + "unlimited": "&eCrea una tienda ilimitada", + "setowner": "&eCambia quién es el propietario de una tienda", + "owner": "&eCambia quién es el propietario de una tienda", + "buy": "&eConvierte una tienda a modo &dCOMPRA", + "sell": "&eConvierte una tienda a modo &dVENTA", + "price": "&eCambia el precio de compra o venta de una de tus tiendas", + "clean": "&eElimina todas las tiendas (cargadas) fuera de existencias", + "find": "&eLocaliza la tienda más cercana de un tipo específico", + "reload": "&eRecarga el archivo config.yml de QuickShop", + "refill": "&eAgrega un número dado de artículos a la tienda", + "empty": "&eElimina todo el stock de la tienda", + "debug": "&eCambia a modo desarrollador", + "create": "&eCrea una nueva tienda en el cofre objetivo", + "fetchmessage": "&eBusca mensajes de tienda no leídos", + "info": "&eMuestra estadísticas de QuickShop", + "paste": "&eCarga automáticamente datos del servidor a Pastebin", + "staff": "&eAdministra el personal de tu tienda", + "remove": "&eQuita la tienda que estás mirando", + "amount": "&eEjecuta tus acciones con una cantidad (Por problemas del complemento de chat)", + "about": "&eMuestra información de QuickShop", + "help": "&eMuestra la ayuda de QuickShop", + "supercreate": "&eCrea una tienda que omita todas las pruebas de seguridad." + } + }, + "signs": { + "selling": "Vendiendo {0}", + "header": "&c{0}", + "buying": "Comprando {0}", + "item": "{0}", + "price": "{0} por unidad.", + "unlimited": "Ilimitado" + }, + "controlpanel": { + "setowner": "&aPropietario: &b{0} &e[&d&lCambiar&e]", + "infomation": "&aPanel de Control de la Tienda:", + "setowner-hover": "&eClick para cambiar el dueño.", + "unlimited": "&aIlimitado: {0} &e[&d&lAlternar&e]", + "unlimited-hover": "&eClick para alternar si la tienda tiene o no límite.", + "mode-selling": "&aModo: &bVenta &e[&d&lAlternar&e]", + "mode-selling-hover": "&eClick para alternar la tienda al modo compra.", + "mode-buying": "&aModo: &bCompra &e[&d&lAlternar&e]", + "mode-buying-hover": "&eClick para alternar la tienda al modo de venta.", + "price": "&aPrecio: &b{0} &e[&d&lEstablecer&e]", + "price-hover": "&eClick para establecer un nuevo precio para esta tienda.", + "refill": "&aRellenar: Reaprovisiona los artículos de la tienda &e[&d&lOK&e]", + "refill-hover": "&eClick para reaprovisionar la tienda.", + "empty": "&aVaciar: Elimina todos los artículos de la tienda &e[&d&lOK&e]", + "empty-hover": "&eClick para limpiar el inventario de la tienda.", + "remove": "&c&l[Eliminar tienda]", + "remove-hover": "&eClick para eliminar esta tienda.", + "commands": { + "setowner": "\/qs setowner [Jugador]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [Nuevo Precio]", + "refill": "\/qs refill [Cantidad]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "|" + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[precio]", + "range": "[rango]", + "amount": "[cantidad]" + }, + "updatenotify": { + "buttontitle": "[Actualizar Ahora]", + "onekeybuttontitle": "[Actualización Automática]", + "list": [ + "¡{0} ha sido lanzada, tú sigues utilizando {1}!", + "¡Boom! Llega la nueva actualización {0}. ¡Actualiza!", + "¡Sorpresa! {0} ha salido, tú estás en {1}", + "Parece que necesitas actualizar, ¡{0} ha sido lanzada!", + "¡Ooops! {0} ha sido lanzada ya, ¡tú estás en {1}!", + "Lo prometo, QS se ha actualizado a {0}, ¿por qué no has actualizado?", + "Arreglando y re... Lo siento, ¡{0} ha sido lanzada!", + "¡Err! Nope, no es un error, ¡{0} acaba de salir!", + "¡OMG! {0} ya salió! ¿Por qué aún usas {1}?", + "Noticias del día: ¡QuickShop ha sido actualizado a {0}!", + "Plugin muerto en combate, ¡deberías actualizar a {0}!", + "El actualizador puede actualizar a {0}, ¡guarda la actualización!", + "Hay una nueva versión, comandante, ¡{0} acaba de salir!", + "Mira, mira---{0} se ha actualizado, sigues usando {1}", + "¡Ahhhhhhh! ¡Nueva versión {0}! ¡Actualiza!", + "¿En qué estás pensando? {0} ¡ya fue lanzada! ¡Actualiza!" + ], + "remote-disable-warning": "§cEsta versión de QuickShop esta marcada como deshabilitado por servidor remoto, quiere decir que esta versión puede tener serios problemas, obtén detalles de nuestra pagina de SpigotMC: {0}. Esta advertencia aparecerá y llenara tu consola de mensajes hasta que uses otra versión no deshabilitada para reemplazar esta, no afectara el funcionamiento de su servidor.", + "label": { + "unstable": "[Inestable]", + "stable": "[Estable]", + "lts": "[LTS]", + "qualityverifyed": "[Calidad]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Maestro]" + } + }, + "shop-removed-cause-ongoing-fee": "&c¡Su tienda en {0} fue removida debido a que no tienes suficiente dinero para mantenerla!", + "digits-reach-the-limit": "&cHas alcanzado el límite de dígitos antes del punto decimal en el precio.", + "complete": "&a¡Terminado!", + "quickshop-gui-preview": "QuickShop GUI Previsualizar Objeto", + "shops-recovering": "Recuperando tiendas desde la copia de seguridad...", + "shops-backingup": "Haciendo copia de seguridad de las tiendas desde la base de datos... ", + "saved-to-path": "El archivo de copia de seguridad se guardó en {0}.", + "backup-failed": "No se puede hacer una copia de seguridad de la base de datos; consulte la consola para obtener más información.", + "translate-not-completed-yet-click": "La traducción del idioma {0} ha completado {1}, ¿Quieres ayudarnos a mejorar la traducción? ¡Haz clic aquí!", + "translate-not-completed-yet-url": "La traducción del idioma {0} ha completado {1}, ¿Quieres ayudarnos a mejorar la traducción? Navegar: {2}", + "language-info-panel": { + "name": "Idioma: ", + "code": "Código: ", + "progress": "Progreso: ", + "help": "Ayúdanos: ", + "translate-on-crowdin": "[Traducir en Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/fi-FI/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/fi-FI/messages.json new file mode 100644 index 0000000..73576b2 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/fi-FI/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Kääntäjä: &b&lSpeek (https:\/\/speek.fi\/)", + "translation-version": "Tuettu versio: Reremake", + "translation-contributors": "Ohjelmointi-apu: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Kielialue: Suomi (fi_FI)", + "language-version": "31", + "not-looking-at-shop": "&cKauppaa ei löytynyt. Sinun pitää katsoa muokattavaa kauppaa päin.", + "no-anythings-in-your-hand": "&cKädessäsi ei ole mitään.", + "no-permission": "&cSinulla ei ole oikeutta tehdä noin.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cSinä et voi rikkoa muiden pelaajien kauppoja luovassa tilassa, vaihda selviytymis tilaan tai yritä käyttää supertyökalua {0}.", + "trading-in-creative-mode-is-disabled": "&cSinä et voi ostaa\/myydä luovassa tilassa.", + "supertool-is-disabled": "&cSupertyökalu on poistettu käytöstä, et voi rikkoa mitään kauppoja.", + "no-double-chests": "&cEt voi luoda tupla-arkkukauppaa", + "not-managed-shop": "&cEt ole tämän kaupan omistaja taikka valvoja", + "shop-already-owned": "&cTuo on jo kauppa!", + "chest-was-removed": "&cKauppa poistettiin onnisteuneesti.", + "price-too-cheap": "&cHinnan pitää olla korkeampi kuin &e${0}", + "no-price-change": "&cTuo ei vaihtaisi kaupan hintaa!", + "you-cant-afford-a-new-shop": "&cKaupan luominen maksaa {0}.", + "player-bought-from-your-store-tax": "&cPelaaja {0} osti {1} {2} kaupasta ja maksoit siitä {3} veroja.", + "you-cant-afford-to-change-price": "&cHinnan vaihtaminen maksaa {0}.", + "success-created-shop": "&cKaupan luonti peruutettiin.", + "success-removed-shop": "&aKauppa poistettiin onnistuneesti", + "shops-arent-locked": "&cMuista, kaupat EI ole suojattu varkailta! Jos haluat suojata arkkusi, käytä esim. LWC- tai Lockette-lisäosaa!", + "shop-creation-cancelled": "&cKaupan luonti peruutettiin.", + "shop-purchase-cancelled": "&cOstaminen peruutettiin.", + "shop-stock-too-low": "&cKaupassa on jäljellä {0} {1}.", + "you-cant-afford-to-buy": "&cTuote maksaa {0}, mutta sinulla on vain {1}.", + "negative-amount": "&cHöpsö! Et voi myydä negatiivisia määriä!", + "not-a-number": "&cSinun tulee antaa numeroarvo.", + "not-a-integer": "&cSinun tulee antaa numeroarvo.", + "player-bought-from-your-store": "&cPelaaja {0} osti kaupastasi {1} {2}.", + "shop-out-of-stock": "&5Kaupastasi koordinaateissa {0}, {1}, {2}, on lopunut {3}.", + "shop-has-no-space": "&cKaupassa on {1} paikkaa tuotteelle {0}.", + "you-dont-have-that-many-items": "&cSinulla on vain {0} {1}", + "the-owner-cant-afford-to-buy-from-you": "&cTuotteen hinta olisi {0}, mutta omistajalla on vain {1}.", + "player-sold-to-your-store": "&aPelaaja {0} myi {1} {2} kauppaasi.", + "shop-out-of-space": "&5Kauppasi koordinaateissa {0}, {1}, {2} on nyt täynnä.", + "fee-charged-for-price-change": "&aMaksoit {0} vahtaaksesi kaupan hinnan.", + "price-is-now": "&aKaupan uusi hinta on nyt &e{0}&a.", + "thats-not-a-number": "&cEpäkelpo numero.", + "no-price-given": "&cAnnathan validin hinnan.", + "average-price-nearby": "&aKeskimääräinen hinta lähettyvillä: &e{0}", + "shop-has-changed": "&cKauppa, jota yritit käyttää, on muuttanut hintaansa tai muita tietoja sen jälkeen kun klikkasit sitä.", + "shop-not-exist": "&cSiellä ei ole kauppaa.", + "nearby-shop-this-way": "&aKauppa on {0} kuutiota kaukana sinusta.", + "no-nearby-shop": "&cKauppoja, jotka myyvät tuotetta {0} ei ole lähistöllä.", + "buying-more-than-selling": "&c&lVAROITUS: &cSinä ostat tuotetta kalliimalla, kun myyt sitä!", + "not-enough-space": "&cSinulla on tilaa vain {0} tuolle.", + "refill-success": "&aUudelleentäyttö onnistui!", + "empty-success": "&aTyhjennys onnistui!", + "admin-shop": "AdminKauppa", + "unknown-owner": "Tuntematon", + "owner-bypass-check": "&aVaihto onnistui! (omistat kaupan)", + "reached-maximum-can-create": "&cOlet tehnyt kauppoja jo {0}\/{1}, eli maksimin määrän.", + "restricted-prices": "&cRajatut hinnat tuotteelle {0}: vähintään {1}, enintään {2}", + "no-enough-money-to-keep-shops": "&cSinulla ei ollut varaa ylläpitää kauppojasi. Kaikki kauppasi on nyt poistettu...", + "nothing-to-flush": "&aSinulla ei ole uusia kauppaviestejä.", + "break-shop-use-supertool": "&eRikot kauppoja käyttäen tyokalua.", + "failed-to-put-sign": "&cKaupan kyltille ei ole tilaa.", + "failed-to-paste": "&cTietojen lataaminen Pastebiniin epäonnistui. Tarkista Internet-yhteystesi ja yritä uudelleen. Palvelimen konsolissa on lisätietoja.", + "warn-to-paste": "&eKerätään tietoja Pastebiniin. Tämä vie hetken. &c&lVaroitus:&c tiedot ovat julkisia yhden viikon ajan - ja se saattaa vuotaa sinun palvelimen asetuksia ja salasanoja. Varmista, että jaat sen vain luotetulle henkilökunnalle tai kehittäjälle.", + "price-too-high": "&cKaupan hinta on liian suuri. Et voi asettaa kaupan hintaa korkeammalle kuin: {0}", + "you-cant-create-shop-in-there": "&cSinulla ei ole oikeutta luoda kauppaa tälle alueelle.", + "unknown-player": "&cKohdepelaajaa ei löydetty. Tarkista, että pelaajan käyttäjänimi on oikein kirjoitettu.", + "shop-staff-cleared": "&cKauppasi henkilökunta poistettiin onnistuneesti", + "shop-staff-added": "&aPelaaja {0} lisättiin onnistuneesti kauppasi henkilökuntaan!", + "shop-staff-deleted": "&aPelaaja {0} poistettiin onnistuneesti kauppasi henkilökunnasta.", + "no-permission-build": "&cEt voi rakentaa kauppaa tänne.", + "success-change-owner-to-server": "&aPalvelin omistaa nyt tämän kaupan", + "flush-finished": "&aViestit päivitettiin onnistuneesti.", + "purchase-failed": "&cOsto epäonnistui. Ole yhteydessä palvelimen ylläpitoon.", + "no-pending-action": "&cSinulla ei ole olemassa olevaa toimintopyyntöä.", + "permission-denied-3rd-party": "&cSinulla ei ole oikeutta 3:n osapuolen lisäosaan [{0}].", + "menu": { + "successful-purchase": "&aOnnistuneesti ostettiin:", + "successfully-sold": "&aOnnistuneesti myytiin", + "item-name-and-price": "&e{0} {1} &ahintaan &e{2}", + "sell-tax": "&aMaksoit &e{0} &averoa.", + "sell-tax-self": "&aOmistat tämän kaupan, joten et maksa veroja.", + "enchants": "&5Lumoukset", + "stored-enchants": "&5Varastoidut lumoukset", + "shop-information": "&aKaupan tiedot", + "owner": "&aOmistaja: {0}", + "item": "&aTuote: &e{0}", + "preview": "&b[esikatsele]", + "space": "&aVapaa tila: &e{0}", + "stock": "&aVarastossa: &e{0}", + "price-per": "&aHinta per &e{0} &a- &e{1}", + "total-value-of-chest": "&aArkun yhteenlaskettu hinta: &e{0}", + "damage-percent-remaining": "&e{0}% &ajäljellä.", + "this-shop-is-buying": "&aTämä kauppa &a&lOSTAA &atuotteita.", + "this-shop-is-selling": "&aTämä kauppa &c&lMYY &atavaroita.", + "effects": "&aEfektit: &e{0}", + "commands": { + "preview": "\/qs hiljainenkatselu {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cOhitetaan QuickShopin lukitus!", + "that-is-locked": "&cTämä kauppa on lukittu.", + "how-many-buy": "&aKirjoita chattiin kuinka monta haluat &c&lOSTAA&a.", + "how-many-sell": "&aKirjoita chattiin kuinka kappaletta monta haluat &a&lMYYDÄ&a. Sinulla on &e{0}&a myytävää tavaraa.", + "not-allowed-to-create": "&cEt luultavasti voi luoda kauppaa tänne.", + "blacklisted-item": "&cTämä tavara on mustalla listalla. Et luultavasti voi myydä sitä", + "how-much-to-trade-for": "&aKirjoita chattiin numeroina, minkä hinnan haluat asettaa tuotteelle &e{0}&a.", + "command": { + "toggle-unlimited": { + "unlimited": "&aKaupassa on nyt rajattomasti tavaroita", + "limited": "&aKauppa ei ole enään rajaton" + }, + "no-owner-given": "&cOmistajaa ei ole asetettu. Käytä &a\/qs setowner &c", + "new-owner": "&aUusi omistaja: &e{0}", + "now-buying": "&aKauppasi &c&lOSTAA&a nyt tuotetta &e{0}", + "now-selling": "&aKauppasi &a&lMYY&a nyt tuotetta &e{0}", + "cleaning": "&aPoistetaan tyhjiä kauppoja...", + "reloading": "&aLadataan uudelleen...", + "cleaned": "&aPoistettu &e{0}&a kauppaa", + "no-type-given": "&cKäytä: \/qs find ", + "no-amount-given": "&cSummaa ei ole annettu. Käytä &a\/qs refill &c", + "now-debuging": "&aOnnistuneesti siirrytty kehittäjätilaan, QuickShop ladataan uudelleen...", + "now-nolonger-debuging": "&aOnnistuneesti siirrytty tuotantotilaan, QuickShop ladataan uudelleen...", + "wrong-args": "&cParametrit eivät täsmänneet, käytä \/qs help katsoaksesi apua", + "description": { + "title": "&aQuickShop-apu", + "unlimited": "&eTekee kaupasta rajattoman", + "setowner": "&eVaihtaa kaupan omistajan", + "owner": "&eVaihtaa kaupan omistajan", + "buy": "&eVaihtaa kaupan &costamaan&e tuotteita", + "sell": "&eVaihtaa kaupan &amyymään &etuotteita.", + "price": "&eVaihtaa osto tai myynti hinnan yhdestä kaupastasi", + "clean": "&ePoistaa kaikki (ladatut) kaupat, jonka varastot ovat tyhjät.", + "find": "&eEtsii lähimmän kaupan haluumallesi tavaralle.", + "reload": "&eLataa QuickShopin config.yml tiedoston uudelleen", + "refill": "&eLisää tietyn määrän tavaroita kauppaan", + "empty": "&eTyhjentää koko varaston kaupasta", + "debug": "&eVaihtaa kehittäjätilaan", + "create": "&eLuo uuden kaupan kohdistettuun arkkuun", + "fetchmessage": "&eHae lukematon kaupan viesti", + "info": "&eNäytä QuickShopin tilastoja", + "paste": "&eLataa automaatisesti palvelimen dataa Pastebiniin", + "staff": "&eHallinnoi kauppasi henkilökuntaa", + "remove": "&ePoista kauppa, jota katsot", + "amount": "&eTee toiminto summalla (chat-ongelmia varten)", + "about": "&eNäytä QuickShop-ohjeistukset", + "help": "&eNäytä QuickShop-apuselitteet", + "supercreate": "&eLuo kauppa ohittamalla kaikki suojaustarkistukset" + } + }, + "signs": { + "selling": "{0} kpl", + "header": "&l{0}", + "buying": "Ostetaan {0}", + "item": "{0}", + "price": "{0} kpl", + "unlimited": "Rajaton" + }, + "controlpanel": { + "setowner": "&aOmistaja: &b{0} &e[&dvaihda&e]", + "infomation": "&aKaupan asetukset:", + "setowner-hover": "&eVaikuttaisi siltä, että haluat vaithaa kaupan omistajaa. Klikkaa!", + "unlimited": "&aRajaton: {0} &e[&dmuuta&e]", + "unlimited-hover": "&eNäyttäisi siltä että haluat muokata kauppaasi, paina ottaaksesi käyttöön tai poistamalla käytöstä.", + "mode-selling": "&aKaupan tila: &aMyydään &e[&dmuuta&e]", + "mode-selling-hover": "&eNäyttäisi siltä että haluat muokata kauppaasi, paina ottaaksesi käyttöön tai poistamalla käytöstä.", + "mode-buying": "&aKaupan tila: &cOstetaan &e[&d&lVaihda&e]", + "mode-buying-hover": "&eNäyttäisi siltä että haluat muokata kauppaa, paina vaihtaaksesi kaupan tila aktiiviseksi tai poistetuksi käytöstä.", + "price": "&aHinta: &b{0} &e[&daseta&e]", + "price-hover": "&eNäyttäisi siltä että haluat muokata kauppaa, paina asetaaksesi uusi hinta.", + "refill": "&aTäydennys: Täydennä kaupan varasto &e[&d&lOK&e]", + "refill-hover": "&eNäyttäisi siltä että haluat muokata kauppaa, paina täydentääksesi kaupan varasto.", + "empty": "&aTyhjennä: Tyhjennä kaupan varasto &e[&d&lOK&e]", + "empty-hover": "&eNäyttäisi siltä että haluat muokata kauppaa, paina tyhjenttäksesi kaupan varasto.", + "remove": "&c&l[Poista kauppa]", + "remove-hover": "&ePoista tämä kauppa klikkaamalla.", + "commands": { + "setowner": "\/qs setowner [Pelaaja]", + "unlimited": "\/qs slientunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [Uusi hinta]", + "refill": "\/qs refill [summa]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[hinta]", + "range": "[säde]", + "amount": "[määrä]" + }, + "updatenotify": { + "buttontitle": "[Päivitä nyt]", + "onekeybuttontitle": "[klikkaa päivittääksesi]", + "list": [ + "Versio {0} on jo julkaistu, käytät edelleen versiota {1}!", + "Pam! Uusi päivitys {0} on tullut! Päivitä!", + "Yllätys! Versio {0} tuli ulos, sinä olet versiossa {1}.", + "Näyttäisi siltä että sinun täytyy päivittää, {0} on julkaistu!", + "Ooops! {0} on julkaistu, sinulla on {1}!", + "Lupaan, että QS on päivitetty versioon {0}, miksi et päivittäisi?", + "Korjataan ja korjataan... Pahoittelen, mutta {0} on päivitetty!", + "Virhe! Ei oikeasti, QS:n uusi versio {0} on julkaistu!", + "OMG! {0} on tullut ulos! Miksi käytät yhä {1}?", + "Päivän uutiset: QuickShop päivittyi versioon {0}!", + "Sinun kannattaisi päivittää QS versioon {0}!", + "Hrrr! Päivitä versioon {0} nyt!", + "Kerron sinulle, että {0} julkaistaisiin!", + "Mä oon jo versiossa {0}! Päivitä! Sä oot viel {1}-versiossa ;)", + "Jeeeeeeee! Uusi päivitys {0} on tullut! Päivitä!", + "Mitä ajattelet? {0} on julkaistu! Päivitä!" + ], + "remote-disable-warning": "&cTämä QuickShop-versio on merkitty toimimattomaksi etäpalvelimelta. Tämä tarkoittaa sitä, että MIKÄÄN tai OSA QuickShopin ominaisuuksista ei toimi tai on pahasti vialla. Lataa uusi versio SpigotMC-sivuiltamme: {0}. Tämä varoitusviesti poistuu, eikä spämmi konsoliasi, kun päivität tämän lisäosan.", + "label": { + "unstable": "[Epävakaa]", + "stable": "[Vakaa]", + "lts": "[LTS]", + "qualityverifyed": "[Laatu]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cKauppasi ({0}) poistettiin, sillä sinulla ei ollut varaa ylläpitää sitä!", + "digits-reach-the-limit": "&cOlet saavuttanut desimaalirajan.", + "complete": "&aValmis!", + "quickshop-gui-preview": "QuickShiop GUI-esikatselu", + "shops-recovering": "Palautetaan kauppoja varmuuskopiosta...", + "shops-backingup": "Varmuuskopioidaan kauppoja tietokannasta... ", + "saved-to-path": "Varmuuskopio tiedosto tallennettiin {0} .", + "backup-failed": "Tietokantaa ei pystytty varmuuskopioimaan, katso konsoli yksityiskohtia varten.", + "translate-not-completed-yet-click": "Kyseisen kielen {0} käännös on valmis {1}, Haluatko sinä auttaa parantamaan käännöstä? Paina tästä!", + "translate-not-completed-yet-url": "Kyseisen kielen {0} käännös on valmis {1}, Haluatko sinä auttaa parantamaan käännöstä? Selaa: {2}", + "language-info-panel": { + "name": "Kieli: ", + "code": "Koodi: ", + "progress": "Edistyminen: ", + "help": "Auta meitä: ", + "translate-on-crowdin": "[Käännä Crowdinissa]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/fr-FR/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/fr-FR/messages.json new file mode 100644 index 0000000..c515dfa --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/fr-FR/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Traducteur : &b&liDrunK & &b&lZenCraft", + "translation-version": "Version suportée: Reremake", + "translation-contributors": "Contributeurs: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Langue: Français (fr_FR)", + "language-version": "31", + "not-looking-at-shop": "&cAucune boutique trouvée. Vous devez être entrain d'en regarder un pendant que vous écrivez votre commande.", + "no-anythings-in-your-hand": "&cVous n'avez aucun objet dans votre main.", + "no-permission": "&cVous n'avez pas la permission de faire ceci.", + "3rd-plugin-build-check-failed": "Un plugin tiers a refusé les vérifications de permission, avez-vous les droits pour construire ici ?", + "no-creative-break": "&cVous ne pouvez pas casser les boutiques des autres joueurs en mode créatif, basculez en mode survie ou essayez d'utiliser le superoutil {0} à la place.", + "trading-in-creative-mode-is-disabled": "&cVous ne pouvez pas utiliser une boutique en mode créatif.", + "supertool-is-disabled": "&cLe superoutil est désactivé, impossible de casser une boutique avec.", + "no-double-chests": "&cVous ne pouvez pas créer de boutique avec un double coffre.", + "not-managed-shop": "&cVous n'êtes pas le propriétaire ou le modérateur de cette boutique", + "shop-already-owned": "&cCe coffre est déjà une boutique.", + "chest-was-removed": "&cLe coffre a été supprimé.", + "price-too-cheap": "&cLe prix doit être supérieur à &e${0}", + "no-price-change": "&cLe prix ne subira aucun changement !", + "you-cant-afford-a-new-shop": "&cLa création d'une boutique coûte {0}.", + "player-bought-from-your-store-tax": "&c{0} a acheté {1} {2} dans ta boutique, et tu as payé {3} de taxes.", + "you-cant-afford-to-change-price": "&cCela coûte {0} de changer le prix de ta boutique.", + "success-created-shop": "&aBoutique créé avec succès.", + "success-removed-shop": "&aBoutique supprimée avec succès.", + "shops-arent-locked": "&cSouvenez-vous que les boutiques ne sont pas protégées contre le pillage! Tu dois les verrouiller ou protéger ta zone pour éviter le vol!", + "shop-creation-cancelled": "&cCréation de la boutique annulée.", + "shop-purchase-cancelled": "&cAchat annulé.", + "shop-stock-too-low": "&cIl ne reste que {0} {1} dans cette boutique.", + "you-cant-afford-to-buy": "&cCette transaction coûte {0}, mais vous ne disposez que de {1}.", + "negative-amount": "&cVous ne pouvez pas échanger une quantité négative !", + "not-a-number": "&cSeul les nombres doivent êtres utilisés, or vous avez écrit {0}", + "not-a-integer": "&cSeul les nombres entiers doivent êtres utilisés, or vous avez écrit {0}", + "player-bought-from-your-store": "&c{0} a acheté {1} {2} dans votre boutique.", + "shop-out-of-stock": "&5Votre boutique aux coordonnées {0}, {1}, {2}, est à court de {3}", + "shop-has-no-space": "&cCette boutique n'a de la place que pour {0} de plus {1}.", + "you-dont-have-that-many-items": "&cVous ne possédez que {0} {1} dans votre inventaire.", + "the-owner-cant-afford-to-buy-from-you": "&cCela coûte {0} mais le propriétaire n'a plus que {1}", + "player-sold-to-your-store": "&a{0} à vendu {1} {2} dans votre boutique.", + "shop-out-of-space": "&5Votre boutique aux coordonnées {0}, {1}, {2}, est pleine.", + "fee-charged-for-price-change": "&aVous payez &c{0}&a pour changer le prix.", + "price-is-now": "&aLe nouveau prix de cette boutique est de: &e{0}", + "thats-not-a-number": "&cNombre invalide.", + "no-price-given": "&cMerci de donner un nombre\/chiffre valide.", + "average-price-nearby": "&aPrix moyen aux alentours de: &e{0}", + "shop-has-changed": "&cLa boutique que vous essayez d'utiliser à changée depuis que vous avez cliqué dessus!", + "shop-not-exist": "&cIl n'y a aucune boutique.", + "nearby-shop-this-way": "&aLa boutique est à {0} blocs de vous.", + "no-nearby-shop": "&cAucune boutique trouvée dans les alentours.", + "buying-more-than-selling": "&cATTENTION: Vous êtes entrain d'acheter des objets plus cher que vous ne les vendez!", + "not-enough-space": "&cIl ne vous reste que {0} place(s) restante(s) pour ceci !", + "refill-success": "&aRemplissage de la boutique effectué avec succès.", + "empty-success": "&aVidé avec succès.", + "admin-shop": "Boutique Admin", + "unknown-owner": "Inconnu", + "owner-bypass-check": "&eVérifications évitées, Echange réussi ! (Tu es propriétaire de la boutique)", + "reached-maximum-can-create": "&cTu as atteint ton nombre de coffre de shop maximal: {0}\/{1}!", + "restricted-prices": "&cPrix restreints {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cTu n'as plus asseez d'argent pour garder tes coffres de shop.. Tout tes coffres ont été supprimés.", + "nothing-to-flush": "&aAucun nouveau message de boutique.", + "break-shop-use-supertool": "&eTu as cassé la boutique en utilisant le super outil.", + "failed-to-put-sign": "&cIl n'y a pas assez de place autour de la boutique pour placer un panneau d'information.", + "failed-to-paste": "&cErreur lors de l'upload des données vers PasteBin, verifier la connection internet et rééssayez. (Voir la console)", + "warn-to-paste": "&eAssemblage de données et upload vers PasteBin, cela peut prendre un moment. &c&lAttention:&c Les données sont gardées publiques pendant UNE semaine, cela peut faire fuiter la config de votre serveur, assurez vous de la partager à des gens de confiances.", + "price-too-high": "&cLe prix est trop haut! Tu ne peux pas mettre un prix supérieur à {0} .", + "you-cant-create-shop-in-there": "&cTu n'as pas la permission de créer une boutique à cet emplacement!", + "unknown-player": "&cLe joueur cible n'existe pas, merci de vérifier le pseudo que tu as entré.", + "shop-staff-cleared": "&aTous les gérants de ton coffre de shop ont été supprimés avec succès!", + "shop-staff-added": "&aLe gérant {0} à été ajouté à ton coffre de shop avec succès!", + "shop-staff-deleted": "&aLe staff {0} à été supprimé de votre boutique avec succès!", + "no-permission-build": "&cTu ne peux pas créer une boutique ici.", + "success-change-owner-to-server": "&aLe propriétaire de la boutique à été définit au Serveur avec succès!", + "flush-finished": "&aMessages communiqués avec succès", + "purchase-failed": "&cEchec de l'achat: Erreur interne, veuillez contacter un administrateur du serveur.", + "no-pending-action": "&cTu n'as aucune action en attente", + "permission-denied-3rd-party": "&cPermission refusée: plugin tiers [{0}].", + "menu": { + "successful-purchase": "&aAchat réussi:", + "successfully-sold": "&aVente réussie:", + "item-name-and-price": "&e{0} {1} &apour &e{2}", + "sell-tax": "&aTu as payé&e{0} &aen taxes.", + "sell-tax-self": "&aCe shop t'appartient donc tu ne payes pas de taxes.", + "enchants": "&5Enchantements", + "stored-enchants": "&5Enchantements Stockés", + "shop-information": "&aInformations sur la boutique :", + "owner": "&aPropriétaire: {0}", + "item": "&aObjet: &e{0}", + "preview": "&b[Prévisualisation de l'objet]", + "space": "&aEspace restant: &e{0}", + "stock": "&aStock restant&e{0}", + "price-per": "&aPrix unitaire de &e{0} &a- &e{1}", + "total-value-of-chest": "&aValeur totale du coffre: &e{0}", + "damage-percent-remaining": "&e{0}% &arestant.", + "this-shop-is-buying": "&aCette boutique &dACHETE&a des objets.", + "this-shop-is-selling": "&aCeette boutique &dVEND&a des objets.", + "effects": "&aEffets", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cContournement d'un verrou de QuickShop !", + "that-is-locked": "&cCe shop est verouillé.", + "how-many-buy": "§aEntrez le nombre d'items que vous souhaitez §bACHETER§a dans le chat. Vous en avez §e{0}§a dans votre inventaire. Entrez §ball§a pour tous les acheter.", + "how-many-sell": "§aEntrez le nombre d'items que vous souhaitez §bVENDRE§a dans le chat. Vous en avez §e{0}§a dans votre inventaire. Entrez §ball§a pour tous les vendres.", + "not-allowed-to-create": "&cVous ne pouvez pas créer un shop ici.", + "blacklisted-item": "&cCet item est blacklisté. Vous ne pouvez pas le vendre.", + "how-much-to-trade-for": "&aEntrez le prix contre lequel vous souhaitez échanger l'item &e{0}&a dans le chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aCe shop est désormais illimité", + "limited": "&aCe shop est désormais limité" + }, + "no-owner-given": "&cPas de propriétaire défini. Utilise &a\/qs setowner &cpour définir un propriétaire.", + "new-owner": "&aNouveau propriétaire: &e{0}", + "now-buying": "&dACHETE &aactuellement des &e{0}", + "now-selling": "&bVEND &aactuellement des &e{0}", + "cleaning": "&aSuppression des shops avec 0 de stock.", + "reloading": "&aRechargement...", + "cleaned": "&e{0} &acoffres de shop ont été supprimés.", + "no-type-given": "&cUtilisation: \/qs find ", + "no-amount-given": "&cAucun montant donné. Utilise &a\/qs refill &c", + "now-debuging": "&aPassage réussi en mode développeur. Rechargement de QuickShop...", + "now-nolonger-debuging": "&aPassage réussi en mode production. Rechargement de QuickShop...", + "wrong-args": "&cLes paramètres ne correspondent pas. Utilise \/qs help pour vérifier l'aide d'utilisation.", + "description": { + "title": "&aAide QuickShop", + "unlimited": "&eRendre un shop illimité", + "setowner": "&eChange le propriétaire du shop", + "owner": "&eChange le propriétaire du shop", + "buy": "&eTransforme le coffre de shop en mode &dACHAT", + "sell": "&eTransforme le coffre de shop en mode &bVENTE", + "price": "&eChange le prix d'achat\/vente d'un de tes coffres de shop.", + "clean": "&eSupprime tout les coffres chargés ayant 0 de stock.", + "find": "&eLocalise le coffre de shop le plus proche d'un type spécifique.", + "reload": "&eRecharge le fichier config.yml pour QuickShop", + "refill": "&eAjoute un nombre donné d'objets à un shop.", + "empty": "&eRetire tout le stock d'un coffre de shop.", + "debug": "&ePasser en mode développeur", + "create": "&eCrée un nouveau shop au coffre cible", + "fetchmessage": "&eRécupérer les messages du shop non lus", + "info": "&eAfficher les statistiques QuickShop", + "paste": "&eTéléchargement automatique des données du serveur vers Pastebin", + "staff": "&eGérer les gérants de ton coffre de shop", + "remove": "&eSupprime le coffre de shop que tu regarde", + "amount": "&eExécuter les actions avec montant(Pour le problème du plugin de chat)", + "about": "&eA propos de QuickShop", + "help": "&eAfficher l'aide QuickShop", + "supercreate": "&eCréer un coffre de shop en contournant tous les contrôles de protection" + } + }, + "signs": { + "selling": "Vente {0}", + "header": "&c{0}", + "buying": "Achat {0}", + "item": "{0}", + "price": "{0} l'unité", + "unlimited": "Illimité" + }, + "controlpanel": { + "setowner": "&aPropriétaire: &b{0} &e[&dChanger&e]", + "infomation": "&aPanneau de controle du shop:", + "setowner-hover": "&eClique pour changer le propriétaire.", + "unlimited": "&aIllimité: {0} &e[&dChanger&e]", + "unlimited-hover": "&eClique pour définir le shop comme illimité.", + "mode-selling": "&aMode du shop: &bVENTE &e[&dChanger&e]", + "mode-selling-hover": "&aClique pour convertir le shop en mode achat.", + "mode-buying": "&aMode du shop: &bACHAT &e[&dChanger&e]", + "mode-buying-hover": "&eClique pour convertir le shop en mode vente.", + "price": "&aPrix: &b{0} &e[&d&lDéfinir&e]", + "price-hover": "&eClique pour définir un nouveau prix au coffre de shop.", + "refill": "&aRéapprovisionnement: &e[&d&lRéapprovisionner&e]", + "refill-hover": "&eClique pour réapprovisionner le shop.", + "empty": "&aVidange du shop: &e[&d&lVider&e]", + "empty-hover": "&eClique pour vider tout les objets du shop.", + "remove": "&c&l[Supprimer le shop]", + "remove-hover": "&eClique pour supprimer ce coffre de shop.", + "commands": { + "setowner": "\/qs setowner [Pseudonyme]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [Nouveau prix]", + "refill": "\/qs refill [Quantité]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[prix]", + "range": "[distance]", + "amount": "[quantité]" + }, + "updatenotify": { + "buttontitle": "[Mettre à jour]", + "onekeybuttontitle": "[Mise à jour instantanée]", + "list": [ + "{0} a été publiée. Vous utilisez encore la version {1} !", + "BOUM! Nouvelle mise à jour {0} disponible !", + "Surprise! La mise à jour {0} est sortie. Vous êtes actuellement sur la version {1}", + "Visiblement vous avez besoin d'une mise à jour... La version {0} a été publiée !", + "OUPS ! La version {0} a déjà été publiée... Vous êtes sur la version {1} !", + "Je vous jure, QuickShop a été mis à jour vers la version {0}, pourquoi vous ne l'avez pas mis à jour?", + "Réparer et ré... Désolé {0} est sortie !", + "Err! Non, ceci n'est pas une erreur. {0} viens d'être publiée !", + "OH MON DIEU ! {0} est disponible ! Pourquoi utilisez vous encore {1} ?", + "Nouveauté de la journée: QuickShop a été mis à jour en {0}", + "Plugin K.I.A, vous devez mettre à jour {0}!", + "Fuze lance la mise à jour {0}, enregistrez la mise à jour!", + "Il y a une mise à jour commandant, {0} viens de sortir!", + "Regarde mon style --- {0} mise à jour, tu as toujours la version {1}", + "Ahhhhhhh! Nouvelle mise à jour {0}!", + "Qu'est-ce que tu penses? {0} Une nouvelle mise à jour publiée!" + ], + "remote-disable-warning": "&cCette version de QuickShop a été désignée comme désactivée par le serveur distant. Cela signifie que cette version peux contenir de sérieux problèmes et bugs. Plus de détails sur notre page SpigotMC: {0}. Cet avertissement apparaitra dans votre console jusqu'à ce que vous utilisiez une version stable de QuickShop. Ceci n'affecte pas le fonctionnement de votre serveur.", + "label": { + "unstable": "[Instable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Qualité]", + "github": "[GitHub]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cTon coffre de shop aux coordonnées {0} a été supprimé car tu n'avais plus assez d'argent pour le garder !", + "digits-reach-the-limit": "&cTu as atteint la limite de décimales dans le prix.", + "complete": "&aAction effectuée", + "quickshop-gui-preview": "Objet d'aperçu de l'interface QuickShop", + "shops-recovering": "Récupération des boutiques à partir de la sauvegarde...", + "shops-backingup": "Sauvegarde des boutiques à partir de la base de données... ", + "saved-to-path": "Le fichier de sauvegarde a été sauvegardé dans {0}.", + "backup-failed": "Impossible de sauvegarder la base de données, vérifiez la console pour plus de détails.", + "translate-not-completed-yet-click": "La traduction de la langue {0} a terminé {1}, Voulez-vous nous aider à améliorer la traduction ? Cliquez ici !", + "translate-not-completed-yet-url": "La traduction de la langue {0} a terminé {1}, Voulez-vous nous aider à améliorer la traduction ? Cliquez ici : {2}", + "language-info-panel": { + "name": "Langue: ", + "code": "Code : ", + "progress": "Progression : ", + "help": "Aidez-nous : ", + "translate-on-crowdin": "[Traduit sur Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/he-IL/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/he-IL/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/he-IL/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/hu-HU/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/hu-HU/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/hu-HU/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/it-IT/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/it-IT/messages.json new file mode 100644 index 0000000..a1ead4b --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/it-IT/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "PapaPinuXIo", + "translation-version": "1.15.1Pro", + "translation-contributors": "Rightdenied", + "translation-country": "Language Zone: English (it_US)", + "language-version": "31", + "not-looking-at-shop": "&cNon è stato trovato nessun QuickShop, devi guardarne uno", + "no-anythings-in-your-hand": "&cNon hai nulla in mano.", + "no-permission": "&c Non hai i permessi per questo.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cNon puoi creare un negozio Doppia Cassa.", + "not-managed-shop": "&cNon sei il proprietario o moderatore del negozio", + "shop-already-owned": "&cQuesto già è un negozio.", + "chest-was-removed": "&cIl cartello è stato rimosso.", + "price-too-cheap": "&cIl prezzo deve essere superiore a &e ${0}", + "no-price-change": "&cQuesto non comporta un cambio di prezzo.", + "you-cant-afford-a-new-shop": "&cIl prezzo per un nuovo negzio è di {0}", + "player-bought-from-your-store-tax": " &c{0} Ha acquistato {1} {2} dal tuo negozio e hai pagato {3} di tasse.", + "you-cant-afford-to-change-price": "&c{0} comprato {1} {2} dal tuo negozio, e tu hai pagato {3} in tasse.", + "success-created-shop": "&cNegozio creato", + "success-removed-shop": "&cNegozio rimosso", + "shops-arent-locked": "&cRICORDA, i negozi NON sono protetti dai furti! Se tu volessi fermare i ladri bloccali con LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCreazione del negozio cancellata", + "shop-purchase-cancelled": "&cAcquisto del negozio cancellato", + "shop-stock-too-low": "&cIl negozio ha solo {0} {1} sinstra", + "you-cant-afford-to-buy": "&cCosta {0}, ma hai solo {1}", + "negative-amount": "&c Hops! non è possibile scambiare importi negativi", + "not-a-number": "&cDevi inserire una cifra, inserisci{0}", + "not-a-integer": "&cDevi inserire una cifra intera, inserisci {0}", + "player-bought-from-your-store": "&c{0}Ha acquistato {1} {2} dal tuo negozio", + "shop-out-of-stock": "&5Il tuo negosio su {0}, {1}, {2}, ha esaurito {3}", + "shop-has-no-space": "&cIl negozio ha spazio solo per {0} in più {1}.", + "you-dont-have-that-many-items": "&cHai solo {0}{1}.", + "the-owner-cant-afford-to-buy-from-you": "&cL'oggetto che vuoi vendere cosa {0} ma il proprietario ha solo {1}", + "player-sold-to-your-store": "e un {0} ha venduto {1} {2} al tuo negozio", + "shop-out-of-space": "&5Il tuo negozio a {0}, {1}, {2} è Pieno", + "fee-charged-for-price-change": "&aPer modificare il prezzo si paga &c{0}", + "price-is-now": "&aIl nuovo prezzo del negozio è &e {0}", + "thats-not-a-number": "&cNon hai inserito nessuna cifra", + "no-price-given": "&cInserisci una cifra Valida", + "average-price-nearby": "&aPrezzo medio nelle vicinanze: &e{0}", + "shop-has-changed": "&cIl negozio che stai utilizzando è cambiato dall'ultima visita", + "shop-not-exist": "&cNon c'era nessun negozio", + "nearby-shop-this-way": "&aIl negozio è a {0} isolati da te", + "no-nearby-shop": "&cNon c'è nessun negozio {0} nelle tue vicinanze", + "buying-more-than-selling": "&cATTENZIONE &aIl prezzo d'acquisto è più alto del prezzo di vendita", + "not-enough-space": "&c Hai spazio solo per {0} in più!", + "refill-success": "&aRifila il successo", + "empty-success": "&aSuccesso vuoto", + "admin-shop": "&6&LNegozio Admin", + "unknown-owner": "&2Anonimo", + "owner-bypass-check": "&eHai bypassato tutti i controlli! Ora sei il proprietario del negozio", + "reached-maximum-can-create": "&cHai raggiunto il limite, possiedi {0} su {1}negozi", + "restricted-prices": "&cPrezzi limitati per {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cNon hai abbastanza soldi per tenere i tuoi negozi! Tutti i negozi sono stati rimossi...", + "nothing-to-flush": "&aNon hai ricevuto nessun nuovo messaggio dal negozio.", + "break-shop-use-supertool": "&ePuoi rompere il negozio usando il SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ja-JP/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ja-JP/messages.json new file mode 100644 index 0000000..363cdfd --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ja-JP/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "翻訳者: ethernetcat", + "translation-version": "サポートバージョン: Reremake", + "translation-contributors": "貢献者: Timtower, Netherfoam, KaiNoMood 及び Mgazul", + "translation-country": "言語圏: 日本語 (ja_JP)", + "language-version": "31", + "not-looking-at-shop": "&cQuickShopが見つかりませんでした。見ている必要があります。", + "no-anythings-in-your-hand": "&cあなたの手には何もありません。", + "no-permission": "&c権限を持っていないため実行できません。", + "3rd-plugin-build-check-failed": "\n一部のサードパーティプラグインが権限チェックを拒否しました。権限が組み込まれていますか?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cダブルチェストショップを作成することはできません。", + "not-managed-shop": "あなたはショップの所有者でもモデレーターでもありません。", + "shop-already-owned": "&cすでにショップです。", + "chest-was-removed": "&cチェストが削除されました。", + "price-too-cheap": "&c価格は&e${0}&c以上である必要があります。", + "no-price-change": "&c価格変更できません!", + "you-cant-afford-a-new-shop": "&c新しいショップを作成するには{0}かかります。", + "player-bought-from-your-store-tax": "&c{0} は {1} {2} をショップから購入し {3} を税で支払いました。", + "you-cant-afford-to-change-price": "&cショップで価格を変更するには {0} かかります。", + "success-created-shop": "&aショップを作成しました。", + "success-removed-shop": "&aショップを削除しました。", + "shops-arent-locked": "&cショップは保護されていません!保護が必要な場合は、LWCやLocketteなどでロックしてください!", + "shop-creation-cancelled": "&cショップの作成をキャンセルしました。", + "shop-purchase-cancelled": "&c購入をキャンセルしました。", + "shop-stock-too-low": "&cショップには {0} {1} しか残っていません", + "you-cant-afford-to-buy": "&c費用は {0} ですが、{1} しかありません。", + "negative-amount": "&cマイナス量を取引できません", + "not-a-number": "&c数値のみが可能ですが {0} を入力しています", + "not-a-integer": "&c整数のみが可能ですが {0} を入力しています", + "player-bought-from-your-store": "&c{0} はショップから {1} {2} を購入しました。", + "shop-out-of-stock": "&5{0}、{1}、{2} のショップで {3} がなくなりました", + "shop-has-no-space": "&cショップには {0} 個以上 {1} 個分のスペースしかありません", + "you-dont-have-that-many-items": "&c{0} {1} しかありません", + "the-owner-cant-afford-to-buy-from-you": "&c{0} 必要ですが {1} しかありません", + "player-sold-to-your-store": "&a{0} があなたのショップに {1} {2} を販売しました", + "shop-out-of-space": "&5{0}, {1}, {2} のショップは一杯です", + "fee-charged-for-price-change": "&a価格変更のため &c{0}&a を支払いました", + "price-is-now": "&a新しい価格は &e{0} &aです", + "thats-not-a-number": "&c無効な番号です", + "no-price-given": "&c有効な価格を設定してください", + "average-price-nearby": "&a近くの平均価格 : &e{0}", + "shop-has-changed": "&cクリックしたので使おうとしたショップが変わりました", + "shop-not-exist": "&cショップがありませんでした", + "nearby-shop-this-way": "&aショップは {0} ブロック離れています", + "no-nearby-shop": "&c近くに {0} と一致するショップはありません", + "buying-more-than-selling": "&c警告 : 売っているアイテムよりも多くを買っています", + "not-enough-space": "&c{0} 個分のスペースしかありません", + "refill-success": "&aRefill 成功", + "empty-success": "&aEmpty 成功", + "admin-shop": "アドミンショップ", + "unknown-owner": "不明", + "owner-bypass-check": "&e全てのチェックをバイパス、取引成功(あなたはショップオーナーです)", + "reached-maximum-can-create": "&cすでに最大 {0} \/ {1} のショップを作成しました", + "restricted-prices": "&c{0} の制限価格 : 最小 {1} , 最大 {2}", + "no-enough-money-to-keep-shops": "&cショップを維持するのに十分な資金がありませんので全てのショップが削除されました", + "nothing-to-flush": "&a新しいショップメッセージはありませんでした", + "break-shop-use-supertool": "&eSuperTool を使ってショップを壊す事ができます", + "failed-to-put-sign": "&cショップの周りに情報看板を配置するのに十分なスペースがありません。", + "failed-to-paste": "&cPastebin へのデータのアップロードに失敗しました。インターネットを確認して、もう一度お試しください。(詳細についてはコンソールをご覧ください)", + "warn-to-paste": "&eデータを収集してPastebinにアップロードするには、しばらく時間がかかる場合があります。&c&l警告&c、データは1週間公開されます。サーバー設定やその他の機密情報が漏洩する可能性があります。&l信頼できるスタッフ\/開発者にのみ送信するようにしてください。", + "price-too-high": "&cショップの価格が高すぎます! {0} より高い価格のショップは作成できません。", + "you-cant-create-shop-in-there": "&cこの場所にショップを作成する権限がありません。", + "unknown-player": "&c目的のプレーヤーが存在しません。入力したユーザー名を確認してください。", + "shop-staff-cleared": "&aショップの全てのスタッフを削除しました。", + "shop-staff-added": "&aショップスタッフに {0} を追加しました。", + "shop-staff-deleted": "&aショップスタッフから {0} を削除しました。", + "no-permission-build": "&cここではショップを作成できません。", + "success-change-owner-to-server": "&aショップの所有者をサーバーに設定しました。", + "flush-finished": "&a未読メッセージの取り出しに成功しました", + "purchase-failed": "&c購入に失敗しました:内部エラー。サーバー管理者に連絡してください。", + "no-pending-action": "&c保留中のアクションはありません", + "permission-denied-3rd-party": "&cアクセス拒否: サードパーティのプラグイン [{0}]", + "menu": { + "successful-purchase": "&a購入に成功しました :", + "successfully-sold": "&a売却に成功しました :", + "item-name-and-price": "&e{0} {1} &aを &e{2}", + "sell-tax": "&a税として &e{0} &aを支払いました", + "sell-tax-self": "&aこのショップの所有者なので税支払はありません", + "enchants": "&5エンチャント", + "stored-enchants": "&5エンチャント保管", + "shop-information": "&aショップ情報 :", + "owner": "&a所有者 : {0}", + "item": "&aアイテム : &e{0}", + "preview": "&b[アイテム閲覧]", + "space": "&a空き : &e{0}", + "stock": "&a在庫 : &e{0}", + "price-per": "&a単価 : &e{0} &a- &e{1}", + "total-value-of-chest": "&aチェストの合計額 : &e{0}", + "damage-percent-remaining": "&a残り &e{0}%", + "this-shop-is-buying": "&aこのショップは &d販売&a です", + "this-shop-is-selling": "&aこのショップは &b買取&a です", + "effects": "&a効果", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cQuickShopロックをバイパスします!", + "that-is-locked": "&cショップはロックされています。", + "how-many-buy": "&aチャットで&b購入&aしたい数を入力してください。&e{0}&aを購入できます。&ball&aで全て購入", + "how-many-sell": "&aチャットで&d販売&aしたい数を入力してください。&e{0}&a持っています。&ball&aで全て販売", + "not-allowed-to-create": "&cあなたはここでショップを作る事ができません", + "blacklisted-item": "&cそのアイテムはブラックリストに載っています。売ることはできません", + "how-much-to-trade-for": "&aチャットで&e {0} &aを取引する金額を入力してください。", + "command": { + "toggle-unlimited": { + "unlimited": "&aショップは無制限になりました", + "limited": "&aショップは制限されています" + }, + "no-owner-given": "&c所有者がありません。&a\/qs setowner <プレイヤー名> &cで設定してください", + "new-owner": "&a新しい所有者 : &e{0}", + "now-buying": "&a現在 &d買取 &e{0}", + "now-selling": "&a現在 &b販売 &e{0}", + "cleaning": "&a在庫ゼロのショップを削除します", + "reloading": "&aリロード中...", + "cleaned": "&e{0}&a ショップを削除しました。", + "no-type-given": "&c使用法: \/qs find <アイテム名>", + "no-amount-given": "&c数がありません。&a\/qs refill <個数> &cを使ってください", + "now-debuging": "&a開発者モードに切り替え成功、QuickShopをリロードしています。", + "now-nolonger-debuging": "&aプロダクションモードに切り替え成功、QuickShopをリロードしています。", + "wrong-args": "&cパラメーターが一致しません。\/qs help を使用してヘルプを確認してください。", + "description": { + "title": "&aQuickShop ヘルプ", + "unlimited": "&eショップを無制限にします。", + "setowner": "&eショップの所有者を変更します。", + "owner": "&eショップの所有者を変更", + "buy": "&eショップを&d買取&eモードに変更します", + "sell": "&eショップを&b販売&eモードに変更します", + "price": "&eいずれかのショップの購入\/販売価格を変更します", + "clean": "&e在庫ゼロの全てのショップを削除します", + "find": "&e指定アイテムの最寄りショップを探します", + "reload": "&econfig.yml をリロードします", + "refill": "&e特定数のアイテムをショップに追加します", + "empty": "&eショップから全ての在庫を削除します", + "debug": "&e開発者モードに切り替えます", + "create": "&eターゲットしたチェストに新しいショップを作成します", + "fetchmessage": "&e未読ショップメッセージを取得", + "info": "&eQuickShop 統計を表示します", + "paste": "&eサーバーデータを Pastebin に自動アップロードします", + "staff": "&eショップスタッフを管理する", + "remove": "&e見ているショップを削除します", + "amount": "&e金額を指定してアクションを実行します(チャットプラグインの問題の場合)", + "about": "&eQuickShopの情報を表示", + "help": "&eQuickShopのヘルプを表示", + "supercreate": "&eすべての保護チェックをバイパスするショップを作成する" + } + }, + "signs": { + "selling": "販売 {0}", + "header": "&c{0}", + "buying": "買取 {0}", + "item": "{0}", + "price": "1つあたり {0}", + "unlimited": "無制限" + }, + "controlpanel": { + "setowner": "&a所有者 : &b{0} &e[&d&l変更&e]", + "infomation": "&aショップコントロールパネル :", + "setowner-hover": "&eクリックで所有者変更します", + "unlimited": "&a無制限 : {0} &e[&d&l切替&e]", + "unlimited-hover": "&eクリックで制限\/無制限を切り替えます", + "mode-selling": "&aショップモード : &b販売 &e[&d&l切替&e]", + "mode-selling-hover": "&eクリックで買取モードに切り替えます", + "mode-buying": "&aショップモード : &b買取 &e[&d&l切替&e]", + "mode-buying-hover": "&eクリックで販売モードに切り替えます", + "price": "&a価格 : &b{0} &e[&d&l変更&e]", + "price-hover": "&eクリックで価格変更します", + "refill": "&aRefill : ショップアイテム追加 &e[&d&l追加&e]", + "refill-hover": "&eクリックでアイテム追加", + "empty": "&aEmpty : ショップアイテム削除 &e[&d&l削除&e]", + "empty-hover": "&eクリックでアイテム削除します", + "remove": "&c&l[ショップ削除]", + "remove-hover": "&eクリックでショップを削除します", + "commands": { + "setowner": "\/qs setowner [プレイヤー名]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [新価格]", + "refill": "\/qs refill [個数]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[価格]", + "range": "[範囲]", + "amount": "[個数]" + }, + "updatenotify": { + "buttontitle": "[更新する]", + "onekeybuttontitle": "[ワンキーアップデート]", + "list": [ + "{0} がリリースされました。まだ {1} を使用しています!", + "新しい {0} がリリースされました、更新しましょう!", + "サプライズ!{0} が出ました。あなたは {1} です", + "更新する必要があるようです。{0} がリリースされました!", + "おっと! {0} がリリースされました。今は {1} です!", + "QuickShopは {0} になりましたが、更新されないのですか?", + "修正して再...申し訳ありませんが {0} がリリースされました!", + "エラー! いいえ、これはエラーではなく、{0} がリリースされたばかりです!", + "ああ、神様! {0} が出ました! まだ {1} を使用しているのはなぜですか?", + "今日のニュース:QuickShop が {0} に更新されました!", + "プラグインK.I.A、{0} に更新する必要があります!", + "フューズはアップデート {0} をフューズしています、アップデートを保存してください!", + "アップデート司令官がいます、{0} が登場しました!", + "私のスタイルを見て--- {0} が更新されましたが、まだ {1} を使用しています", + "ああ! 新しい更新 {0}! 更新を!", + "何を考えてる? {0} がリリースされました! 更新しましょう!" + ], + "remote-disable-warning": "&cこのバージョンのQuickShopは、リモートサーバーでは無効と記されています。つまり、このバージョンには深刻な問題がある可能性があります。SpigotMCページから詳細を取得します:{0}。この警告が表示され、無効になっていない他のバージョンを使用してこのバージョンを置き換えるまで、コンソールに表示が続きます。サーバーの実行には影響しません。", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[GitHub]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&c{0}のショップは十分な資金がなかったため削除されました", + "digits-reach-the-limit": "&c価格の小数点以下の制限に達しました。", + "complete": "&a完了!", + "quickshop-gui-preview": "QuickShop GUI プレビューアイテム", + "shops-recovering": "バックアップからショップを復元しています...", + "shops-backingup": "データベースからショップをバックアップしています... ", + "saved-to-path": "バックアップファイルは {0} に保存されました。", + "backup-failed": "データベースをバックアップできません。詳細についてはコンソールを確認してください。", + "translate-not-completed-yet-click": "言語 {0} の翻訳は {1} が完了しています。翻訳の改善に協力いただけますか?ここをクリック!", + "translate-not-completed-yet-url": "言語 {0} の翻訳は {1} が完了しています。翻訳の改善に協力いただけますか?参照: {2}", + "language-info-panel": { + "name": "言語: ", + "code": "コード: ", + "progress": "進行状況: ", + "help": "ヘルプ: ", + "translate-on-crowdin": "[Crowdinで翻訳]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ko-KR/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ko-KR/messages.json new file mode 100644 index 0000000..251cd4e --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ko-KR/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Encode : UTF-8\n번역자 : WaterFrost,FLASH,ruddls030", + "translation-version": "지원 버전: Reremake", + "translation-contributors": "기여자: Timtower, Netherfoam, KaiNoMood, Mgazul", + "translation-country": "언어 지역: 한국어 (Ko)", + "language-version": "31", + "not-looking-at-shop": "&c퀵샵을 찾을수 없습니다. 당신은 반드시 상점을 보고있어야 합니다.", + "no-anythings-in-your-hand": "&c당신의 손에 아무것도 없습니다.", + "no-permission": "&c이것을 하기위해선 권한이 필요합니다.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&c당신은 DoubleChest 상점을 만들 수 없습니다.", + "not-managed-shop": "&c당신은 상점의 주인 또는 관리자가 아닙니다", + "shop-already-owned": "&c상점이 이미 있습니다.", + "chest-was-removed": "&c상자는 제거되었습니다.", + "price-too-cheap": "&c가격은 반드시 &e${0} 원 &c보다 높아야합니다.", + "no-price-change": "&c그렇게 되면 가격 변동이 없을 거예요!", + "you-cant-afford-a-new-shop": "&c새 상점 생성에 {0} 원이 소모됩니다!", + "player-bought-from-your-store-tax": "&c{0} 님이 유저님의 상점 에서 {1} {2} 을(를) 구입했으며 유저님은 세금으로 {3} 원 을(를) 지불하셨습니다!", + "you-cant-afford-to-change-price": "&c상점 가격을 변경하는 데 {0}원이 소모됩니다!", + "success-created-shop": "&c상점을 만들었습니다.", + "success-removed-shop": "&c상점을 제거했습니다.", + "shops-arent-locked": "&c기억하세요, 상점는 도난으로부터 보호되지 않습니다! 도난을 막으려면 LWC, Lockette 등 을 이용하여 상자를 잠구세요!", + "shop-creation-cancelled": "&c상점 개설을 취소했습니다.", + "shop-purchase-cancelled": "&c구매를 취소했습니다.", + "shop-stock-too-low": "&c상점에는 {0} {1} 개의 상품이 남아 있습니다.", + "you-cant-afford-to-buy": "&c비용은 {0} 원 이지만, 당신은 {1} 원 만 가지고 있습니다.", + "negative-amount": "&c멍청이! 음수로 가격을 정할 수는 없습니다.", + "not-a-number": "&c숫자만 입력할 수 있습니다만, 당신은 {0}을 입력했습니다.", + "not-a-integer": "&c숫자만 입력할 수 있습니다만, 당신은 {0}을 입력했습니다.", + "player-bought-from-your-store": "&c{0} 님이 유저님의 상점에서 {1} {2} 을 (를) 구매했습니다.", + "shop-out-of-stock": "&5{0}, {1}, {2}에 있는 유저님의 가게에 {3}이 (가) 부족합니다.", + "shop-has-no-space": "&c가게에는 {0} 이상의 {1}의 공간 만 있습니다.", + "you-dont-have-that-many-items": "&c유저님은 {0} {1} 밖에 없습니다.", + "the-owner-cant-afford-to-buy-from-you": "&c비용은 {0}이지만, 당신은 {1}만 가지고 있습니다.", + "player-sold-to-your-store": "&a{0}님이 {1} {2}을 (를) 유저님의 상점에 판매했습니다.", + "shop-out-of-space": "&5유저님의 {0}, {1}, {2}에 있는 상점이 가득 찼습니다.", + "fee-charged-for-price-change": "&a가격을 변경하려면 &c{0}&a원을 지불해야합니다.", + "price-is-now": "&a상점의 새로운 가격은 &e{0}원 입니다.", + "thats-not-a-number": "&c잘못된 숫자입니다. 확인하시고 다시 입력하세요.", + "no-price-given": "&c유효한 가격을 주세요.", + "average-price-nearby": "&a인근 평균 가격: &e{0}원", + "shop-has-changed": "&c유저님이 사용하려고 했던 상점이 유저님이 클릭한 이후로 변경되었습니다!", + "shop-not-exist": "&c상점이 없습니다.", + "nearby-shop-this-way": "&a상점은 당신을 기준으로 {0}블록 떨어진 곳에 있습니다.", + "no-nearby-shop": "&c근처에 {0}을(를) 파는 일치하는 상점이 없습니다.", + "buying-more-than-selling": "&c주의 : 당신이 구매하려는 수량이 판매하는 수량보다 많습니다!", + "not-enough-space": "&c이 중 {0}개를 더 사용할 수 있는 공간만 있습니다!", + "refill-success": "&a성공적으로 채웠습니다.", + "empty-success": "&a성공적으로 비웠습니다.", + "admin-shop": "관리자 상점", + "unknown-owner": "알 수 없음", + "owner-bypass-check": "&e모든 조사를 통과하여, 거래를 완료했습니다! (당신은 상점 주인입니다.)", + "reached-maximum-can-create": "&c당신은 이미 최대 {0}\/{1}개의 상점을 생성했습니다!", + "restricted-prices": "&c{0}에 대한 가격이 제한되었습니다. 최소 {1}원, 최대 {2}원", + "no-enough-money-to-keep-shops": "&c당신은 당신의 상점유지에 충분한 돈이 없습니다! 모든상점이 제거 됩니다...", + "nothing-to-flush": "&a새로운 상점 메세지가 없습니다.", + "break-shop-use-supertool": "&e 당신은 SuperTool을 이용해 상점을 파괴할 수 있습니다.", + "failed-to-put-sign": "&c상점정보 팻말을 설치하기 위한 충분한 공간이 없습니다.", + "failed-to-paste": "&cPastebin에 데이터 업로드에 실패했습니다. 인터넷을 확인한 후 다시 시도하십시오. (자세한 내용은 콘솔을 참조하세요.)", + "warn-to-paste": "&e데이터를 수집하고 Pastebin에 업로드하는 데 시간이 걸릴 수 있습니다. &c&l주의!&c. 데이터는 일주일 동안 공개되며 서버 구성이 유출될 수 있으므로 신뢰할 수 있는 직원\/개발자에게만 전송해야 합니다.", + "price-too-high": "&c상점의 가격이 너무 높습니다! 당신은 {0}원 이상의 상점을 만들수 없습니다!", + "you-cant-create-shop-in-there": "&c당신은 이 위치에 상점을 설치할 수 있는 권한이 없습니다.", + "unknown-player": "&c대상 플레이어가 없습니다. 유저이름을 확인해주세요.", + "shop-staff-cleared": "&a성공적으로 당신 상점의 모든 관리자를 해고하였습니다.", + "shop-staff-added": "&a성공적으로 {0}님을 당신의 상점에 고용하였습니다.", + "shop-staff-deleted": "&a성공적으로 {0}님을 당신의 상점에서 해고하였습니다.", + "no-permission-build": "&c당신은 이 위치에 상점을 만들 수 없습니다.", + "success-change-owner-to-server": "&a성공적으로 상점 소유자를 서버로 설정했습니다.", + "flush-finished": "&a성공적으로 거래 기록을 제거하였습니다.", + "purchase-failed": "&c구매 실패: 내부 오류. 서버의 관리자에게 문의하세요", + "no-pending-action": "&c처리 대기중인 내역이 없습니다.", + "permission-denied-3rd-party": "&c액세스가 거부되었습니다: 제삼자 플러그인 [{0}].", + "menu": { + "successful-purchase": "&a성공적으로 구매했습니다:", + "successfully-sold": "&a성공적으로 판매했습니다:", + "item-name-and-price": "&e{0}개&a의 &e{1} &a(총 &e{2}&a)", + "sell-tax": "&a당신은 세금으로 &e{0}원&a을 지불했습니다.", + "sell-tax-self": "&a당신은 이 상점의 주인 이므로 세금이 제외됩니다.", + "enchants": "&5부여된 마법", + "stored-enchants": "&5부여 가능한 마법", + "shop-information": "&a상점 정보 :", + "owner": "&a주인 : {0}", + "item": "&a아이템 : &e{0}", + "preview": "&b[아이템 미리보기]", + "space": "&a빈 공간 : &e{0}", + "stock": "&a재고품 &e{0}", + "price-per": "&e{0}&a의 개당 가격 &a- &e{1}", + "total-value-of-chest": "&a상자의 총 가치 : &e{0}원", + "damage-percent-remaining": "&a남은 내구도 : &e{0}%", + "this-shop-is-buying": "&a이 상점은 아이템을 &d구매&a중인 상점입니다.", + "this-shop-is-selling": "&a이 상점은 아이템을 &d판매&a중인 상점입니다.", + "effects": "&a효과", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&a QuickShop 잠금 무시!", + "that-is-locked": "&c이 상점은 잠겼습니다.", + "how-many-buy": "&a채팅으로 원하는 &b구매&a 개수를 입력해주세요. 당신은 &e{0}&a개를 구매할 수 있습니다. &ball&a을 입력해 전부 구매 가능.", + "how-many-sell": "&a채팅으로 원하는 &b판매&a 개수를 입력해주세요. 당신은 &e{0}&a개를 판매할 수 있습니다. &ball&a을 입력해 전부 판매 가능.", + "not-allowed-to-create": "&c 당신은 이곳에 상점을 만들수 없습니다.", + "blacklisted-item": "&c이 아이템은 금지된 아이템입니다. 당신은 이 아이템을 판매할 수 없습니다.", + "how-much-to-trade-for": "&a채팅에 &e{0}&a와 교환할 금액을 입력해주세요.", + "command": { + "toggle-unlimited": { + "unlimited": "&a상점의 재고를 무제한으로 설정했습니다. (관리자 상점으로 설정됩니다.)", + "limited": "&a상점의 재고를 제한으로 설정했습니다. (유저 상점으로 설정됩니다.)" + }, + "no-owner-given": "&c주인이 없습니다. &a\/qs setowner <플레이어 이름>&c을 사용하여 주인을 지정하세요.", + "new-owner": "&a새 주인 : &e{0}", + "now-buying": "&a이제 &e{0}&a를 구매합니다.", + "now-selling": "&a이제 &e{0}&a를 판매합니다.", + "cleaning": "&a재고가 0개인 상점 정리중....", + "reloading": "&a리로드 중...", + "cleaned": "&e{0}개&a의 상점을 정리했습니다", + "no-type-given": "&c사용법: \/qs find <아이템 이름>", + "no-amount-given": "&a<개수>&c가 주어지지 않았습니다. &a\/qs refill <개수>&c를 사용하여 물품을 보충하세요.", + "now-debuging": "&a개발자 모드로 변경 완료. Quickshop 리로드 중...", + "now-nolonger-debuging": "&a일반 모드로 변경 완료. Quickshop 리로드 중...", + "wrong-args": "&c맞는 명령어가 아닙니다. \/qs help 를 사용하여 도움말을 확인하세요", + "description": { + "title": "&aQuickshop 도움말", + "unlimited": "&e상점 재고를 무제한으로 만듭니다.", + "setowner": "&e상점 소유자를 변경합니다.", + "owner": "&e상점 소유자를 변경합니다.", + "buy": "&e상점을 &d구매&e로 전환하였습니다.", + "sell": "&e상점을 &b판매&e로 전환하였습니다.", + "price": "&e상점의 구매\/판매 가격을 변경합니다.", + "clean": "&e재고가 0인 모든 상점을 제거합니다", + "find": "&e특정 유형의 가장 가까운 상점을 찾습니다.", + "reload": "&eQuickshop의 config.yml 파일을 다시 불러옵니다.", + "refill": "&e상점의 아이템을 입력한 숫자만큼 채웁니다.", + "empty": "&e상점의 모든 재고를 제거합니다.", + "debug": "&e개발자 모드로 변경합니다.", + "create": "&e바라보는 상자에 새 상점을 만듭니다.", + "fetchmessage": "&e읽지 않은 상점 메시지를 가져옵니다.", + "info": "&eQuickShop의 통계를 표시합니다", + "paste": "&e서버 데이터를 Pastebin에 자동 업로드합니다.", + "staff": "&e당신의 상점 관리자를 관리합니다.", + "remove": "&e바라보고 있는 상점을 제거합니다.", + "amount": "&e거래 숫자 입력을 명령어로 시행합니다(채팅 플러그인 충돌 문제)", + "about": "&eQuickShop 플러그인의 정보를 봅니다.", + "help": "&eQuickShop 명령어 목록을 봅니다.", + "supercreate": "&e모든 보호를 우회하고 상점을 개설합니다." + } + }, + "signs": { + "selling": "판매 {0}", + "header": "&c{0}", + "buying": "구매 {0}", + "item": "{0}", + "price": "개당 {0}", + "unlimited": "무제한" + }, + "controlpanel": { + "setowner": "&a주인: &b{0} &e[&d&l바꾸기&e]", + "infomation": "&a상점 제어판:", + "setowner-hover": "&e눌러서 주인 변경", + "unlimited": "&a무제한:{0} &e[&d&l변경&e]", + "unlimited-hover": "&e상점 재고가 무제한일 경우 눌러서 전환", + "mode-selling": "&a상점 모드: &b판매중 &e[&d&l변경&e]", + "mode-selling-hover": "&e눌러서 구매모드로 전환", + "mode-buying": "&a상점 모드: &b구매중 &e[&d&l변경&e]", + "mode-buying-hover": "&e눌러서 판매모드로 전환", + "price": "&a가격: &b{0} &e[&d&l설정&e]", + "price-hover": "&e눌러서 새로운 가격 설정", + "refill": "&a채우기: 상점의 아이템을 채우시겠습니까? &e[&d&l네&e]", + "refill-hover": "&e눌러서 채우기", + "empty": "&a제거 : 상점의 모든 아이템을 제거하시겠습니까? &e[&d&l네&e]", + "empty-hover": "&e눌러서 상점 비우기", + "remove": "&c&l[상점 제거]", + "remove-hover": "&e 클릭해서 상점 삭제.", + "commands": { + "setowner": "\/qs setowner [플레이어]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [새 가격]", + "refill": "\/qs refill [수량]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[가격]", + "range": "[범위]", + "amount": "[수량]" + }, + "updatenotify": { + "buttontitle": "[지금 업데이트]", + "onekeybuttontitle": "[즉시 업데이트]", + "list": [ + "{0}이\/가 출시되었습니다, 현재 {1}을\/를 사용중입니다.", + "짠! {0} 출시! 업데이트하세요!", + "짜잔! {0} 출시! 당신은 아직 {1}", + "보아하니 당신은 업데이트가 필요한 것처럼 보이네요 {0}가 공개됐어요!", + "저런! {0} 가 공개됐어요! 당신은 {1} 인데!", + "내가 약속하는데 퀵샵은 {0} 으로 업데이트 되었습니다 왜 업데이트 안해요?", + "수정 후 재로ㄷ... 죄송합니다 {0}이 출시했습니다!", + "에러! 가 아니라 {0} 이제 출시!", + "세상에! {0}가 출시됐어요! 왜 아직도 {1}을 사용하죠?", + "오늘의 뉴스: 퀵샵이 {0} 으로 업데이트 되었습니다!", + "플러그인 사망.. 당신은 {0}으로 업데이트 해야해요!", + "{0}이 나왔는데 업데이트 할꺼야 안할꺼야!", + "업데이트가 있습니다, 사령관님! {0} 이 출시했습니다!", + "내 스타일좀 봐! {0} 업데이트! 넌 아직 {1}을 쓰는중!", + "ㅋㅋㅋㅋㅋㅋㅋㅋ 새로운 {0} 업데이트!", + "무슨 생각이세요? {0} 버전이 출시됐는데! 업데이트하세요!" + ], + "remote-disable-warning": "이 버전의 QuickShop은 원격 서버에 의해 비활성화되어 있습니다. 이 버전에는 심각한 문제가 있을 수 있습니다. SpigotMC 페이지에서 자세한 내용을 확인하십시오 : {0}.이 경고는 당신의 콘솔에 허가된 버전을 사용할 때까지 뜰 것입니다. 서버 구동에는 영향을 주지 않습니다.", + "label": { + "unstable": "[불안정함]", + "stable": "[안정됨]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&c{0} 위치에 있는 당신의 상점이 유지 비용이 없어 제거되었습니다!", + "digits-reach-the-limit": "&c가격의 소수점 뒤 숫자 개수의 한계에 도달했습니다.", + "complete": "&a완료!", + "quickshop-gui-preview": "퀵샵 GUI 미리보기 아이템", + "shops-recovering": "상점을 백업본으로부터 복구하는 중입니다...", + "shops-backingup": "상점을 데이터베이스로부터 백업하는 중입니다... ", + "saved-to-path": "백업 파일이 {0}에 저장되었습니다.", + "backup-failed": "데이터베이스에 백업할 수 없습니다, 자세한 내용은 콘솔을 확인해주세요.", + "translate-not-completed-yet-click": "{0} 언어의 번역이 {1} 완료되었습니다, 번역을 향상시키고 싶으신가요? 여기를 클릭하세요!", + "translate-not-completed-yet-url": "{0} 언어의 번역이 {1} 완료되었습니다, 번역을 향상시키고 싶으신가요? 다음 사이트를 방문하세요: {2}", + "language-info-panel": { + "name": "언어: ", + "code": "코드: ", + "progress": "진행도: ", + "help": "도움: ", + "translate-on-crowdin": "[Crowdin에서 번역하기]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/nl-NL/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/nl-NL/messages.json new file mode 100644 index 0000000..0a9895c --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/nl-NL/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Vertaler: Ghost_chu", + "translation-version": "ondersteunende versie: Reremake", + "translation-contributors": "Bijdragers: Timtower, Nederfoam, KaiNoMood en Mgazul", + "translation-country": "Taal Zone: Engels (nl_US)", + "language-version": "31", + "not-looking-at-shop": "&cgeen QuickShop gevonden, u moet naar een shop kijken.", + "no-anythings-in-your-hand": "&cEr zit niets in je hand.", + "no-permission": "&cJe hebt hiervoor geen rechten.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cJe kunt de Dubbele Kist winkel niet aanmaken.", + "not-managed-shop": "Je bent niet de eigenaar of beheerder van de winkel", + "shop-already-owned": "&cDat is al een winkel.", + "chest-was-removed": "&cDe kist is verwijderd.", + "price-too-cheap": "&cPrice moet groter zijn dan &e${0}", + "no-price-change": "&cDat leidt niet tot een prijswijziging!", + "you-cant-afford-a-new-shop": "&cHet maken van een nieuwe winkel kost {0}.", + "player-bought-from-your-store-tax": "&c{0} kocht {1} {2} in uw winkel en u heeft {3} aan belastingen betaald.", + "you-cant-afford-to-change-price": "&cHet kost {0} om de prijs in uw winkel te wijzigen.", + "success-created-shop": "&aWinkel aangemaakt.", + "success-removed-shop": "&aWinkel verwijderd.", + "shops-arent-locked": "&cOnthoud, winkels zijn NIET beschermd tegen diefstal! Als je dieven wilt stoppen, vergrendel het met LWC, Lockette, etc!", + "shop-creation-cancelled": "&cMaken van je winkel geannuleerd.", + "shop-purchase-cancelled": "&cAankoop van je winkel geannuleerd.", + "shop-stock-too-low": "&cDe winkel heeft nog maar {0} {1} over", + "you-cant-afford-to-buy": "&cDat kost {0}, maar je hebt {1}", + "negative-amount": "&cDerp, kan geen negatieve aantallen verhandelen", + "not-a-number": "&cEr kunnen alleen cijfers zijn, maar je voert {0} in", + "not-a-integer": "&cEr kunnen alleen cijfers zijn, maar je voert {0} in", + "player-bought-from-your-store": "&c{0} heeft {1} {2} gekocht in uw winkel.", + "shop-out-of-stock": "&5Uw winkel op {0}, {1}, {2}, heeft geen {3} meer", + "shop-has-no-space": "&cDe winkel heeft alleen ruimte voor {0} {1} meer.", + "you-dont-have-that-many-items": "&cJe hebt slechts {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cDat kost {0}, maar de koper heeft alleen {1}", + "player-sold-to-your-store": "&a{0} verkocht {1} {2} aan uw winkel.", + "shop-out-of-space": "&5Uw winkel op {0}, {1}, {2}, is nu vol.", + "fee-charged-for-price-change": "&aU betaalt &c{0}&a om de prijs te wijzigen.", + "price-is-now": "&aDe nieuwe winkel priis is &e{0}", + "thats-not-a-number": "&cOngeldig nummer", + "no-price-given": "&cVul een geldige prijs in, aub.", + "average-price-nearby": "Gemiddelde prijs in de buurt", + "shop-has-changed": "De winkel die je wou gebruiken is veranderd sinds de laatste keer dat je hem gebruikte!", + "shop-not-exist": "Er was geen winkel.", + "nearby-shop-this-way": "De winkel is {0} blokken van jou verwijderd.", + "no-nearby-shop": "Geen passende winkel {0} in de buurt.", + "buying-more-than-selling": "Waarschuwing: Je koopt items voor meer dan de verkoopprijs!", + "not-enough-space": "Je hebt niet genoeg {0} ruimte voor meer!", + "refill-success": "Hervullen geslaagd", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/no-NO/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/no-NO/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/no-NO/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/pl-PL/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/pl-PL/messages.json new file mode 100644 index 0000000..b3fb6d2 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/pl-PL/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Tłumacz: NieOGEL, NeonDmn i PLKaratusPL", + "translation-version": "Wspierana wersja: Reremake", + "translation-contributors": "Współautorzy: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Język: Polski (pl_PL)", + "language-version": "31", + "not-looking-at-shop": "&cNie znaleziono sklepu, musisz patrzeć się na sklep.", + "no-anythings-in-your-hand": "&cW twojej ręce nic nie ma.", + "no-permission": "Nie masz na to uprawnień.", + "3rd-plugin-build-check-failed": "Niektóre wtyczki firm trzecich odmówiły sprawdzenia uprawnień, czy masz tam uprawnienia wbudowane?", + "no-creative-break": "&cNie możesz zniszczyć sklepów innych graczy w trybie kreatywnym, przełącz się na tryb przetrwania lub zamiast tego spróbuj użyć supernarzędzia {0}.", + "trading-in-creative-mode-is-disabled": "&cNie możesz handlować ze sklepem w trybie kreatywnym.", + "supertool-is-disabled": "&cSupernarzędzie jest wyłączone, nie może zniszczyć żadnego sklepu.", + "no-double-chests": "&cNie możesz stworzyć sklepu z podwójną skrzynią.", + "not-managed-shop": "&cNie jesteś właścicielem lub moderatorem sklepu", + "shop-already-owned": "jest już tu sklep.", + "chest-was-removed": "&cSklep został usunięty.", + "price-too-cheap": "&cCena musi być większa niż &e${0}", + "no-price-change": "&cCena nie została zmieniona!", + "you-cant-afford-a-new-shop": "&cMusisz mieć {0} aby zrobić nowy sklep.", + "player-bought-from-your-store-tax": "&c{0} zakupił {1} {2} z twojego sklepu, i zapłacił {3} podatku.", + "you-cant-afford-to-change-price": "&cMusisz mieć {0} aby zmienić cenę w sklepie.", + "success-created-shop": "&aUtworzono sklep.", + "success-removed-shop": "&aSklep usunięty.", + "shops-arent-locked": "&cPamiętaj, że sklepy NIE są chronione przed kradzieżą! Jeśli chcesz zatrzymać złodziei, zamknij je za pomocą LWC, Lockette itd.!", + "shop-creation-cancelled": "&cAnulowano tworzenie sklepu.", + "shop-purchase-cancelled": "&cAnulowano zakup w sklepie.", + "shop-stock-too-low": "&cW sklepie zostało {0} {1} przedmiotów", + "you-cant-afford-to-buy": "&cTo kosztuje {0}, a ty masz tylko {1}", + "negative-amount": "&cYYY... nie można używać ujemnych cen xD", + "not-a-number": "&cMoże być tylko liczba, ale wpiszesz {0}", + "not-a-integer": "&cMoże być tylko liczba całkowita, ale wpiszesz {0}", + "player-bought-from-your-store": "&c{0} kupił {1} {2} z twojego sklepu.", + "shop-out-of-stock": "&5W twoim sklepie {0}, {1}, {2}, zabrakło {3}", + "shop-has-no-space": "&cSklep ma miejsce tylko na {0} więcej {1}.", + "you-dont-have-that-many-items": "&cPosiadasz tylko {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cTo kosztuje {0} ale właściciel ma tylko {1}", + "player-sold-to-your-store": "&a{0} sprzedał ci {1} {2}.", + "shop-out-of-space": "&5Twój sklep na {0}, {1}, {2}, jest już pełny.", + "fee-charged-for-price-change": "&aZapłaciłeć &c{0}&a zmieniając cenę.", + "price-is-now": "&aNowa cena sklepu to &e{0}", + "thats-not-a-number": "&cNieprawidłowa liczba", + "no-price-given": "&cPodaj poprawną cenę.", + "average-price-nearby": "&aŚrednia cena w pobliżu: &e{0}", + "shop-has-changed": "&cSklep, który używasz zmienił się w trakcie!", + "shop-not-exist": "&cSklep nie istnieje.", + "nearby-shop-this-way": "&aSklep jest {0} bloków od ciebie.", + "no-nearby-shop": "&cBrak w pobliżu sklepów pasujących do {0}.", + "buying-more-than-selling": "&cUWAGA: Kupujesz przedmioty za więcej niż sprzedajesz!", + "not-enough-space": "&cMasz miejsce tylko na kolejne {0} przedmiotów!", + "refill-success": "&aNapełniono", + "empty-success": "&aWyczyszczono", + "admin-shop": "Sklep Administracyjny", + "unknown-owner": "Nieznany", + "owner-bypass-check": "&eWszystkie sprawdzania zostały pominięte. Wymiana udana! (Jesteś właścicielem sklepu)", + "reached-maximum-can-create": "&cJuż posiadasz maksymalną liczbę sklepów: {0}\/{1}", + "restricted-prices": "&cCena ograniczona dla {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cNie miałeś wystarczająco pieniędzy, by utrzymać swoje sklepy! Wszystkie sklepy zostały teraz usunięte...", + "nothing-to-flush": "&aBrak nowych wiadomości ze sklepów.", + "break-shop-use-supertool": "&eMożesz rozbić sklep za pomocą SuperTool.", + "failed-to-put-sign": "&cZa mało miejsca, by umieścić tabliczkę.", + "failed-to-paste": "&cNie udało się przesłać danych do Pastebin. Sprawdź połączenie z internetem i spróbuj ponownie. (Szczegółowe informacje na ten temat w konsoli)", + "warn-to-paste": "&eGromadzenie danych i przesyłanie ich do Pastebin może trochę potrwać. &c&lUwaga &c, dane są upubliczniane przez tydzień, może to spowodować wyciek z konfiguracji serwera oraz innych poufnych danych, upewnij się, że wysyłasz je tylko do swojego personelu\/dewelopera.", + "price-too-high": "&cZbyt wysoka cena sklepu! Nie można utworzyć takiego, którego cena jest wyższa niż {0}.", + "you-cant-create-shop-in-there": "&cNie masz uprawnień do utworzenia sklepu w tej lokalizacji.", + "unknown-player": "&cGracz nie istnieje, sprawdź nazwę użytkownika, którą wpisałeś.", + "shop-staff-cleared": "&aPomyślnie usunięto wszystkich graczy z twojego sklepu.", + "shop-staff-added": "&aPomyślnie dodano gracza {0} do twojego sklepu.", + "shop-staff-deleted": "&aPomyślnie usunięto gracza {0} z twojego sklepu.", + "no-permission-build": "&cNie możesz zrobić tutaj sklepu.", + "success-change-owner-to-server": "&aZ powodzeniem zmieniono właściciela sklepu na Server.", + "flush-finished": "&aPomyślnie wyczyszczono wiadomości.", + "purchase-failed": "&cZakup nieudany: Błąd wewnętrzny, skontaktuj się z administratorem.", + "no-pending-action": "&cNie masz żadnych oczekujących działań", + "permission-denied-3rd-party": "&cOdmowa dostępu: wtyczka innej firmy [{0}]", + "menu": { + "successful-purchase": "&aZakupiono:", + "successfully-sold": "&aSprzedano:", + "item-name-and-price": "&e{0} {1} &aza &e{2}", + "sell-tax": "&aZapłaciłeś &e{0} &aw podatkach.", + "sell-tax-self": "&aTo twój sklep, więc nie płacisz podatków.", + "enchants": "&5Enchanty", + "stored-enchants": "&5Przechowywane Enchanty", + "shop-information": "&aInfo:", + "owner": "&aWłaściciel: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Podgląd Itemu]", + "space": "&aMiejsce: &e{0}", + "stock": "&aIlość &e{0}", + "price-per": "&aCena za &e{0} &a- &e{1}", + "total-value-of-chest": "&aIlość w skrzyni: &e{0}", + "damage-percent-remaining": "&e{0}% &aZostało.", + "this-shop-is-buying": "&aTen sklep &dSKUPUJE&a itemy.", + "this-shop-is-selling": "&aTen sklep &bSPRZEDAJE&a itemy.", + "effects": "&aEfekty", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cOmijanie blokady Quick Shop!", + "that-is-locked": "&cTen sklep jest zamknięty.", + "how-many-buy": "&aWpisz ilość jaką chcesz &bKUPIĆ&a na chat. Wpisz &ball&a, jeśli chcesz kupić wszystko.", + "how-many-sell": "&aWpisz ilość jaką chcesz &dSPRZEDAĆ&a na chat. Posiadasz &e{0}&a przedmiotów. Wpisz &ball&a, jeśli chcesz sprzedać wszystko.", + "not-allowed-to-create": "&cTu nie zrobisz sklepu.", + "blacklisted-item": "&cTen item jest na czarnej liście. Nie możesz go sprzedawać", + "how-much-to-trade-for": "&aPodaj cenę przedmiotu &e{0}&a na chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aSklep jest teraz nieograniczony", + "limited": "&aSklep jest teraz limitowany" + }, + "no-owner-given": "&cNie podano właściciela. Użyj &a\/qs setowner &c", + "new-owner": "&aNowy Właściciel: &e{0}", + "now-buying": "&aTeraz &dSKUPUJESZ&a &e{0}", + "now-selling": "&aTeraz &dSPRZEDAJESZ&a &e{0}", + "cleaning": "&aUsuwanie sklepów z pustymi inwentarzami...", + "reloading": "&aPrzeładowanie...", + "cleaned": "&aUsunięto &e{0}&aze sklepu", + "no-type-given": "&cUżycie: \/qs find ", + "no-amount-given": "&cNie podano ilości. Użyj &a\/qs refill &c", + "now-debuging": "&aPomyślnie przełączono się do trybu developerskiego. Przeładuj QuickShop...", + "now-nolonger-debuging": "&aPomyślnie przełączono się do trybu produkcji. Przeładuj QuickShop...", + "wrong-args": "&cOpcja nie istnieje, użyj \/qs help aby uzyskać pomoc.", + "description": { + "title": "&aPomoc QuickShop", + "unlimited": "&eTworzy nieograniczony sklep", + "setowner": "&eZmień właściciela sklepu", + "owner": "&eZmień właściciela sklepu", + "buy": "&eZmień rodzaj sklepu na tryb &dKUP", + "sell": "&eZmień rodzaj sklepu na tryb &bSPRZEDAŻ", + "price": "&eZmień cenę kupna\/sprzedaży w sklepie", + "clean": "&eUsuwa wszystkie (załadowane) sklepy z pustym inwentarzem", + "find": "&eLokalizuje najbliższy sklep określonego typu.", + "reload": "&ePrzeładowuje plik config.yml dla QuickShop.", + "refill": "&eDodaje daną liczbę przedmiotów do sklepu", + "empty": "&eUsuwa cały zapas ze sklepu", + "debug": "&ePrzejdź w tryb deweloperski", + "create": "&eTworzy nowy sklep na skrzyni", + "fetchmessage": "&ePobierz nieprzeczytaną wiadomość ze sklepu", + "info": "&ePokaż statystyki QuickShop", + "paste": "&eAutomatyczny upload danych serwera do Pastebin", + "staff": "&eZarządzaj personelem sklepu", + "remove": "&eUsuwa sklep na który patrzysz", + "amount": "&eWykonaj za swoje działania z kwotą (w przypadku problemu z wtyczką czatu)", + "about": "&ePokaż informację o QuickShop", + "help": "&ePokaż pomoc dla QuickShop", + "supercreate": "&eUtwórz sklep z obejściem ochrony" + } + }, + "signs": { + "selling": "Kup {0}", + "header": "&c{0}", + "buying": "Sprzedaj {0}", + "item": "{0}", + "price": "{0} za 1 szt.", + "unlimited": "Nieograniczony" + }, + "controlpanel": { + "setowner": "&aWłaściciel: &b{0} &e[&d&lZmień&e]", + "infomation": "&aPanel kontrolny sklepu:", + "setowner-hover": "&eKliknij, aby zmienić właściciela.", + "unlimited": "&aNieograniczony: {0} &e[&d&lZmień&e]", + "unlimited-hover": "&eKliknij, aby przełączyć, jeśli sklep jest nieograniczony.", + "mode-selling": "&aTryb sklepu: &bSPRZEDAŻ &e[&d&lZmień&e]", + "mode-selling-hover": "&eKliknij, aby zmienić sklep na tryb kupowania.", + "mode-buying": "&aTryb sklepu: &bKUP &e[&d&lZmień&e]", + "mode-buying-hover": "&eKliknij, aby zmienić sklep na tryb sprzedawania.", + "price": "&aCena: &b{0} &e[&d&lUstaw&e]", + "price-hover": "&eKliknij, aby ustawić nową cenę dla sklepu.", + "refill": "&aUzupełnianie: Uzupełnij sklep &e[&d&lOK&e]", + "refill-hover": "&eKliknij, aby uzupełnić sklep.", + "empty": "&aCzyszczenie: Wyczyść sklep &e[&d&lOK&e]", + "empty-hover": "&eKliknij, aby wyczyścić sklep.", + "remove": "&c&l[Usuń sklep]", + "remove-hover": "&eKliknij, żeby usunąć sklep.", + "commands": { + "setowner": "\/qs setowner [Gracz]", + "unlimited": "\/qs slientunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [Nowa cena]", + "refill": "\/qs refill [Ilość]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[cena]", + "range": "[zakres]", + "amount": "[ilość]" + }, + "updatenotify": { + "buttontitle": "[Aktualizuj Teraz]", + "onekeybuttontitle": "[Aktualizacja OneKey]", + "list": [ + "Wersja {0} jest już dostępna! Wciąż używasz {1}!", + "BUM!!! Nowy update! {0}", + "Niespodzianka! Nowy update {0}. Wciąż używasz {1}!", + "Wygląda na to, że przyda ci się mała zmiana wersji. Wersja {0} jest już dostępna!", + "Ups! Wersja {0} jest już dostępna! A ty wciąż na {1}...", + "Zaufaj mi, nowy update {0} już jest, czemu by nie skorzystać?", + "Ładowanie skl... a jednak nie :D |UPDATE {0}|!", + "Hmm.. tak, tak... diagnozuję update {0}!", + "OMG! Właśnie wyszło {0}, dlaczego ciągle siedzisz na {1}?", + "Dzisiaj w faktach po faktach: {0} już jest!", + "Przed dalszym użytkowaniem {1} skontaktuj się z lekarzem, lub farmaceutą, lub użyj {0}.", + "Jesteś naszym 1.000.000 klientem! Wygrałeś update do {0}!", + "Adminie! Twoje królestwo jest zagrożone, nalegam na przejście do wersji {0}!", + "Nie, przyjacielu! Patrz na mnie! Stara wersja przeminie {0}, nowa {1} jest wieczna!", + "Ahhhhhhh! Nowy update {0}! Pobieraj Teraz!", + "Słyszałeś? Wersja {0} już jest!" + ], + "remote-disable-warning": "&cTa wersja QuickShop jest oznaczona jako wyłączona przez zdalny serwer, co oznacza, że ta wersja może mieć poważny problem, pobierz szczegóły ze strony SpigotMC: {0}. To ostrzeżenie będzie się wyświetlać i spamować konsolę, dopóki nie użyjesz innej, nie wyłączonej wersji, która nie wypływa na działanie serwera.", + "label": { + "unstable": "[Niestabilny]", + "stable": "[Stabilny]", + "lts": "[LTS]", + "qualityverifyed": "[Jakość]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Mistrz]" + } + }, + "shop-removed-cause-ongoing-fee": "&cTwój sklep w {0} został usunięty, ponieważ nie miałeś wystarczająco dużo pieniędzy, aby go utrzymać!", + "digits-reach-the-limit": "&cOsiągnąłeś limit cyfr po kropce w cenie.", + "complete": "&aZakończony!", + "quickshop-gui-preview": "Podgląd produktu QuickShop", + "shops-recovering": "Odzyskiwanie sklepów z kopii zapasowej...", + "shops-backingup": "Tworzenie kopii zapasowej sklepów z bazy danych... ", + "saved-to-path": "Plik kopii zapasowej został zapisany w {0}.", + "backup-failed": "Nie można wykonać kopii zapasowej bazy danych, sprawdź konsolę, aby uzyskać szczegóły.", + "translate-not-completed-yet-click": "Tłumaczenie języka {0} zostało ukończone w {1}, Chcesz pomóc nam ulepszyć tłumaczenie? Kliknij tutaj!", + "translate-not-completed-yet-url": "Tłumaczenie języka {0} zostało ukończone w {1}, Chcesz pomóc nam ulepszyć tłumaczenie? Przeglądaj: {2}", + "language-info-panel": { + "name": "Język: ", + "code": "Kod: ", + "progress": "Postęp: ", + "help": "Pomóż nam: ", + "translate-on-crowdin": "[Tłumacz na Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/pt-BR/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/pt-BR/messages.json new file mode 100644 index 0000000..6d3ceb4 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/pt-BR/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Tradutores: Ghost_chu, caneva20", + "translation-version": "Versão de suporte: Reremake", + "translation-contributors": "Contribuidores: Timtower, Netherfoam, KaiNoMood e Mgazul", + "translation-country": "Zona do idioma: Português Brasileiro (pt_BR)", + "language-version": "31", + "not-looking-at-shop": "Nenhuma loja encontrada, você precisa estar olhando para uma.", + "no-anythings-in-your-hand": "&cNão há nada na sua mão.", + "no-permission": "&cVocê não tem permissão para fazer isso.", + "3rd-plugin-build-check-failed": "Permissão para construir negada, você tem permissão para construir aqui?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cVocê não pode criar a loja com baú duplo.", + "not-managed-shop": "&cVocê não é o proprietário ou moderador da loja", + "shop-already-owned": "&cIsso já é uma loja.", + "chest-was-removed": "&cO baú foi removido.", + "price-too-cheap": "&cO preço precisa ser maior do que &e${0}", + "no-price-change": "&cIsso não resultaria em uma alteração de preço!", + "you-cant-afford-a-new-shop": "&cCusta {0} para criar uma nova loja.", + "player-bought-from-your-store-tax": "&c{0} comprou {1} {2} da sua loja e você pagou {3} em impostos.", + "you-cant-afford-to-change-price": "&cCusta {0} para alterar o preço na sua loja.", + "success-created-shop": "&aLoja criada.", + "success-removed-shop": "&aLoja removida.", + "shops-arent-locked": "Lembre-se, as lojas não estão protegidas de roubo! Se você quer parar ladrões, bloqueie-as com LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCriação de loja cancelada.", + "shop-purchase-cancelled": "&cCompra cancelada.", + "shop-stock-too-low": "&cA loja só tem {0} {1} restantes", + "you-cant-afford-to-buy": "&cIsso custa {0}, mas você tem apenas {1}", + "negative-amount": "&cDuh, não é possível negociar montantes negativos", + "not-a-number": "&cSó pode haver número, mas você digitou {0}", + "not-a-integer": "&cSó pode ser um número, mas você digitou {0}", + "player-bought-from-your-store": "&c{0} comprou {1} {2} de sua loja.", + "shop-out-of-stock": "&5Sua loja ({0}, {1}, {2}), se esgotou em {3}", + "shop-has-no-space": "&cA loja só tem espaço para mais {0} de {1}.", + "you-dont-have-that-many-items": "&cVocê só tem {0} de {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cIsso custa {0} mas o proprietário só tem {1}", + "player-sold-to-your-store": "&a{0} vendeu {1} {2} na sua loja.", + "shop-out-of-space": "&5A sua loja ({0}, {1}, {2}), está cheia.", + "fee-charged-for-price-change": "&aVocê pagou &c{0}&a para alterar o preço.", + "price-is-now": "&aO novo preço da loja é &e{0}", + "thats-not-a-number": "&cNumero inválido", + "no-price-given": "&cPor favor, insira um preço válido.", + "average-price-nearby": "&aPreço médio ao redor: &e{0}", + "shop-has-changed": "&cA loja que você tentou usar mudou desde que você clicou nela!", + "shop-not-exist": "&cNão há uma loja.", + "nearby-shop-this-way": "&aA loja está a {0} blocos de você.", + "no-nearby-shop": "&cNenhuma loja de {0} por perto.", + "buying-more-than-selling": "&cAVISO: Você está comprando itens por mais do que está vendendo eles!", + "not-enough-space": "&cVocê só tem espaço para mais {0} disso!", + "refill-success": "&aRe-estocado com sucesso", + "empty-success": "&aEsvaziado com sucesso", + "admin-shop": "AdminShop", + "unknown-owner": "Desconhecido", + "owner-bypass-check": "&eIgnorado todas as verificações, operação bem sucedida! (Você é o dono da loja)", + "reached-maximum-can-create": "&cVocê já criou o máximo de lojas! ({0}\/{1})", + "restricted-prices": "&cRestrito preços de {0} para {1} no mínimo e {2} no máximo.", + "no-enough-money-to-keep-shops": "&cVocê não tinha dinheiro suficiente para manter suas lojas! Agora, todas as lojas foram removidas...", + "nothing-to-flush": "&aVocê não tem nenhuma nova mensagem de suas lojas.", + "break-shop-use-supertool": "&eVocê pode quebrar a loja usando a SuperTool.", + "failed-to-put-sign": "&cNão há espaço suficiente ao redor da loja para colocar a placa de informações.", + "failed-to-paste": "&cFalha ao enviar os dados para o Pastebin, verifique a sua internet e tente novamente. (Veja o console para mais detalhes)", + "warn-to-paste": "&eColetando dados e enviando eles para o Pastebin, isso pode demorar um pouco. &c&lAviso&c, Os dados são mantidos públicos por uma semana, pode vazar a configuração do servidor e outras informações confidenciais. Certifique-se de enviá-lo apenas para sua &equipe\/desenvolvedor confiável.", + "price-too-high": "&c O preço da loja é muito alto! Você não pode criar uma que tenha o preço superior a {0}.", + "you-cant-create-shop-in-there": "&cVocê não tem permissão para criar uma loja neste local.", + "unknown-player": "&cEsse jogador não existe, por favor, verifique o nick que você digitou.", + "shop-staff-cleared": "&aTodos os ajudantes da sua loja foram removidos.", + "shop-staff-added": "&a{0} adicionado à equipe de ajudantes da sua loja.", + "shop-staff-deleted": "&a{0} foi removido da equipe de ajudantes da sua loja.", + "no-permission-build": "&cVocê não pode construir uma loja aqui.", + "success-change-owner-to-server": "&aO proprietário da loja foi definido como Servidor.", + "flush-finished": "&aTodas as mensagens foram limpas.", + "purchase-failed": "&cA compra falhou: Erro interno, entre em contato com o administrador do servidor.", + "no-pending-action": "&cVocê não tem nenhuma ação pendente", + "permission-denied-3rd-party": "&cPermissão negada: plugin de terceiros [{0}].", + "menu": { + "successful-purchase": "&aComprado com sucesso:", + "successfully-sold": "&aVendido com sucesso:", + "item-name-and-price": "&e{0} {1} &apor &e{2}", + "sell-tax": "&aVocê pagou &e{0} &aem impostos.", + "sell-tax-self": "&aVocê é dono dessa loja, portanto, não paga impostos.", + "enchants": "&5Encantamentos", + "stored-enchants": "&5Encantamentos armazenados", + "shop-information": "&aInformações da loja:", + "owner": "&aProprietário: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Pré-visualizar Item]", + "space": "&aEspaço: &e{0}", + "stock": "&aEstoque &e{0}", + "price-per": "&aPrice por &e{0} &a- &e{1}", + "total-value-of-chest": "&aValor total do baú: &e{0}", + "damage-percent-remaining": "&e{0}% &aRestante.", + "this-shop-is-buying": "&aEsta loja está &dCOMPRANDO&a itens.", + "this-shop-is-selling": "&aEsta loja está &bVENDENDO&a itens.", + "effects": "&aEfeitos", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cIgnorarando um bloqueio da loja!", + "that-is-locked": "&cEssa loja está bloqueada.", + "how-many-buy": "&aEscreva quantos você deseja &bCOMPRAR&a no chat. Você pode comprar até &e{0}&a. Digite &ball&a para comprar tudo.", + "how-many-sell": "&aEscreva quantos você deseja &bVENDER&a no chat. Você pode vender até &e{0}&a. Digite &ball&a para vender tudo.", + "not-allowed-to-create": "&cVocê não pode criar uma loja aqui.", + "blacklisted-item": "&cEste item está na lista negra. Você não pode vendê-lo", + "how-much-to-trade-for": "&aDigite por quanto você deseja trocar um &e{0}&a no chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aLoja agora é ilimitada", + "limited": "&aLoja agora é limitada" + }, + "no-owner-given": "&cNenhum proprietário informado. Use &a\/qs setowner &c", + "new-owner": "&aNovo proprietário: &e{0}", + "now-buying": "&aAgora &dCOMPRANDO &e{0}", + "now-selling": "&aAgora &bVENDENDO &e{0}", + "cleaning": "&aLimpando lojas com 0 de estoque...", + "reloading": "&aRecarregando...", + "cleaned": "&aLimpo {0}&e lojas", + "no-type-given": "&cUse: \/qs find ", + "no-amount-given": "&cNenhum valor informado. Use &a\/qs refill &c", + "now-debuging": "&aAlterado para o modo de desenvolvedor, recarregando QuickShop...", + "now-nolonger-debuging": "&aAlterado para o modo de produção, recarregando QuickShop...", + "wrong-args": "&cParâmetros não correspondem, use \/qs help para verificar a ajuda", + "description": { + "title": "&aAjuda do QuickShop", + "unlimited": "&etorna uma loja ilimitada", + "setowner": "&eMuda o proprietário da loja", + "owner": "&eMuda o proprietário da loja", + "buy": "&eConverte uma loja para o modo de &dCOMPRA&", + "sell": "&eConverte uma loja para o modo de &bVENDA&", + "price": "&eAltera o preço de compra\/venda de uma de suas lojas", + "clean": "&eRemove todas as lojas (carregadas) com 0 de estoque", + "find": "&eLocaliza a loja mais próxima de um tipo específico.", + "reload": "&eReinicia a config.yml do QuickShop", + "refill": "&eAdiciona um dado número de itens a uma loja", + "empty": "&eRemove todo o estoque de uma loja", + "debug": "&eMuda para o modo de desenvolvedor", + "create": "&eCria uma nova loja no baú alvo", + "fetchmessage": "&eBusca mensagens da loja ainda não lidas", + "info": "&eMostra estatísticas do QuickShop", + "paste": "&eCarrega automaticamente os dados do servidor para o Pastebin", + "staff": "&eGerenciar os ajudantes da sua loja", + "remove": "&eRemova a loja alvo", + "amount": "&eExecuta suas ações com quantia (Para questão do plugin do chat)", + "about": "&eMostrar detalhes do QuickShop", + "help": "&eMostrar ajuda do QuickShop", + "supercreate": "&eCria uma loja ignorando todas as verificações de proteção" + } + }, + "signs": { + "selling": "Vendendo {0}", + "header": "&c{0}", + "buying": "Comprando {0}", + "item": "{0}", + "price": "{0} cada", + "unlimited": "Ilimitado" + }, + "controlpanel": { + "setowner": "&aProprietário: &b{0} &e[&d&lMudar&e]", + "infomation": "&aPainel de Controle da Loja:", + "setowner-hover": "&eClique para alterar o proprietário.", + "unlimited": "&aIlimitado: {0} &e[&d&lMudar&e]", + "unlimited-hover": "&eClique para alternar se a loja é ilimitada.", + "mode-selling": "&aModo da loja: &bVenda &e[&d&lMudar&e]", + "mode-selling-hover": "&eClique para converter a loja para o modo de compra.", + "mode-buying": "&aModo da loja: &bCompra &e[&d&lMudar&e]", + "mode-buying-hover": "&eClique para converter a loja para o modo de venda.", + "price": "&aPreço: &b{0} &e[&d&lMudar&e]", + "price-hover": "&eClique para definir um novo preço para a loja.", + "refill": "&aRe-estocar: Re-estoca os itens da loja &e[&d&lOK&e]", + "refill-hover": "&eClique para re-estocar a loja.", + "empty": "&aEsvaziar: Remover todos os itens &e[&d&lOK&e]", + "empty-hover": "&eClique para limpar o inventário da loja.", + "remove": "&c&l[Remover Loja]", + "remove-hover": "&eClique para remover esta loja.", + "commands": { + "setowner": "\/qs setowner [jogador]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [NOVO PREÇO]", + "refill": "\/qs refill [quantidade]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[preço]", + "range": "[distância]", + "amount": "[quantidade]" + }, + "updatenotify": { + "buttontitle": "[Atualizar agora]", + "onekeybuttontitle": "[Atualização em um clique]", + "list": [ + "{0} foi liberado, você ainda está usando {1}!", + "Boom! Nova atualização {0} chegando, atualize!", + "Surpresa! {0} saiu, você está em {1}", + "Parece que você precisa atualizar, {0} foi lançado!", + "Ooops! {0} foi liberado, você está em {1}!", + "Eu prometo, QS foi atualizado para {0}, por que você ainda não atualizou?", + "Corrigindo e re... Desculpe {0} foi lançado!", + "Erro! Não, isso não é um erro, {0} foi lançado!", + "MEU! {0} saiu! Por que você ainda está usando {1}?", + "Notícias de Hoje: O QuickShop foi atualizado para {0}!", + "Plugin K.I.A, Você deveria atualizar para {0}!", + "Fuze está fazendo a atualização {0}, salve a atualização!", + "Há uma atualização comandante, {0} acabou de sair!", + "Olhe meu estilo---{0} atualizado, você ainda está usando {1}", + "Ahhhhhhh! Nova atualização {0}! Atualize!", + "O que cê tá esperando? {0} foi lançado! Atualize!" + ], + "remote-disable-warning": "&cEsta versão do QuickShop está marcada como desativada pelo servidor remoto, o que significa que esta versão pode ter problemas sérios, obtenha detalhes na nossa página do SpigotMC: {0}. Este aviso irá aparecer e enviar spam ao console até que você use outra versão não desabilitada para substituir esta, não comprometa o seu servidor!", + "label": { + "unstable": "[Instável]", + "stable": "[Estável]", + "lts": "[LTS]", + "qualityverifyed": "[Qualidade]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cSua loja em {0} foi removida porque você não teve dinheiro suficiente para mantê-la!", + "digits-reach-the-limit": "&cVocê atingiu o limite de dígitos depois do ponto no preço.", + "complete": "&aComplete!", + "quickshop-gui-preview": "Item de Pré-visualização da loja", + "shops-recovering": "Recuperando lojas do backup...", + "shops-backingup": "Fazendo backup das lojas do banco de dados... ", + "saved-to-path": "O arquivo de backup foi salvo em {0}.", + "backup-failed": "Não é possível fazer backup do banco de dados, verifique o console para detalhes.", + "translate-not-completed-yet-click": "A tradução do idioma {0} está completa {1}. Você quer nos ajudar a melhorar a tradução? Clique aqui!", + "translate-not-completed-yet-url": "A tradução do idioma {0} está completa {1}. Você quer nos ajudar a melhorar a tradução? Clique aqui {2}!", + "language-info-panel": { + "name": "Idioma: ", + "code": "Código: ", + "progress": "Progresso: ", + "help": "Nos Ajude: ", + "translate-on-crowdin": "[Traduza no Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/pt-PT/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/pt-PT/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/pt-PT/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ro-RO/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ro-RO/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ro-RO/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ru-RU/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ru-RU/messages.json new file mode 100644 index 0000000..d384fd8 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/ru-RU/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Переводчики: Redase, turikhay", + "translation-version": "Поддерживаемая версия: Reremake", + "translation-contributors": "Авторы: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Языковой регион: Русский (ru_RU)", + "language-version": "31", + "not-looking-at-shop": "&cQuickShop не найден. Вы должны смотреть на сундук.", + "no-anythings-in-your-hand": "&cУ вас нет предметов в руках.", + "no-permission": "&cУ вас нет прав на это.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cВы не можете создавать магазин из двойного сундука.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cЭто уже магазин.", + "chest-was-removed": "&cСундук был удален.", + "price-too-cheap": "&cЦена должна быть больше &e${0}", + "no-price-change": "&cЭто действие не привело к изменению цены!", + "you-cant-afford-a-new-shop": "&cСоздание магазина стоит {0}.", + "player-bought-from-your-store-tax": "&c{0} купил {1} {2} в вашем магазине, и вы заплатили {3} налога.", + "you-cant-afford-to-change-price": "&cСмена стоимости в вашем магазине стоит {0}.", + "success-created-shop": "&aМагазин создан.", + "success-removed-shop": "&aМагазин удалён.", + "shops-arent-locked": "&cПомните, магазины НЕ защищены от краж! Если вы хотите остановить воров, защищайте сундуки с помощью LWC, Lockette, и других плагинов для привата сундуков!", + "shop-creation-cancelled": "&cСоздание магазина отменено.", + "shop-purchase-cancelled": "&cПокупка в магазине отменена.", + "shop-stock-too-low": "&cВ магазине осталось лишь {0} {1}", + "you-cant-afford-to-buy": "&cЭто стоит {0}, но у вас только {1}", + "negative-amount": "&cВведите положительное число", + "not-a-number": "&cМожет быть только номер, но вы вводите {0}", + "not-a-integer": "&cМожет быть только целое число, но вы вводите {0}", + "player-bought-from-your-store": "&c{0} купил {1} {2} в вашем магазине.", + "shop-out-of-stock": "&5Ваш магазин на координатах {0}, {1}, {2}, исчерпал количество {3}", + "shop-has-no-space": "&cМагазин может вместить ещё {0} {1}.", + "you-dont-have-that-many-items": "&cУ вас только {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cЭто стоит {0} но владелец имеет только {1}", + "player-sold-to-your-store": "&a{0} продал {1} {2} вашему магазину.", + "shop-out-of-space": "&5Ваш магазин на координатах {0}, {1}, {2}, теперь полон.", + "fee-charged-for-price-change": "&aЗаплатите &c{0}&a чтобы сменить стоимость.", + "price-is-now": "&aНовая стоимость в магазине это &e{0}", + "thats-not-a-number": "&cНеверное значение", + "no-price-given": "&cПожалуйста укажите верную цену.", + "average-price-nearby": "&aСредняя цена: &e{0}", + "shop-has-changed": "&cМагазин, с которым вы пытаетесь взаимодействовать, был изменен", + "shop-not-exist": "&cЗдесь не было магазина.", + "nearby-shop-this-way": "&aМагазин в {0} блоках от вас.", + "no-nearby-shop": "&cНет магазинов, соответствующих {0} поблизости.", + "buying-more-than-selling": "&cВНИМАНИЕ: Вы покупаете предметы дороже чем продаёте!", + "not-enough-space": "&cУ вас есть место ещё для {0} этого!", + "refill-success": "&aПополнение успешно", + "empty-success": "&aОпустошение успешно", + "admin-shop": "Магазин администрации", + "unknown-owner": "Неизвестно", + "owner-bypass-check": "&eВсе проверки пройдены, удачная сделка! (Вы владелец магазина)", + "reached-maximum-can-create": "&cВы уже создали максимум {0}\/{1} магазинов!", + "restricted-prices": "&cОграниченные цены для {0}: минимум {1}, максимум {2}", + "no-enough-money-to-keep-shops": "&cУ вас не хватило денег, чтобы держать свои магазины! Все магазины удалены...", + "nothing-to-flush": "&aУ вас нет новых продаж в магазинах.", + "break-shop-use-supertool": "&eВы сломали магазин с помощью SuperTool.", + "failed-to-put-sign": "&cНет места чтобы разместить табличку.", + "failed-to-paste": "&cОшибка загрузки информации в Pastebin, проверьте подключение к интернету. (Посмотрите сообщения в консоли).", + "warn-to-paste": "&eСбор данных и загрузка в Pastebin, это может занять некоторое время. &c&lВнимание&c, данные хранятся в открытом доступе в течение одной недели, это может привести к утечке конфигурации вашего сервера, убедитесь, что вы отправляете их только своему доверенному лицу \/ разработчику.", + "price-too-high": "&cСлишком высокая цена в магазине! Вы не можете задавать цену выше, чем {0}.", + "you-cant-create-shop-in-there": "&cУ вас нет прав создавать магазины в этом месте.", + "unknown-player": "&cУказанный игрок не существует, проверьте его имя.", + "shop-staff-cleared": "&aУспешно удалены все совладельцы.", + "shop-staff-added": "&a {0} успешно добавлен в совладельцы магазина.", + "shop-staff-deleted": "&a {0} успешно удален из совладельцев магазина.", + "no-permission-build": "&cВы не можете построить магазин в этом месте.", + "success-change-owner-to-server": "&aСервер установлен как владелец магазина.", + "flush-finished": "&aСообщения успешно очищены.", + "purchase-failed": "&cОшибка покупки: Ошибка, свяжитесь с администратором сервера.", + "no-pending-action": "&cУ вас нет ожидающих действий", + "permission-denied-3rd-party": "&cДоступ запрещен: Сторонний плагин [{0}].", + "menu": { + "successful-purchase": "&aВы приобрели:", + "successfully-sold": "&aВы продали:", + "item-name-and-price": "&e{0} {1} &aза &e{2}", + "sell-tax": "&aНалог составил &e{0} &ain.", + "sell-tax-self": "&aВы владелец этого магазина, поэтому с вас не взять налог.", + "enchants": "&5Чары", + "stored-enchants": "&5Наложенные чары", + "shop-information": "&aИнформация о магазине:", + "owner": "&aВладелец: {0}", + "item": "&aПредмет: &e{0}", + "preview": "&b[Предпросмотр предмета]", + "space": "&aСвободное место: &e{0}", + "stock": "&aДоступно: &e{0}", + "price-per": "&aЦена за &e{0} &a- &e{1}", + "total-value-of-chest": "&aВсего магазинов: &e{0}", + "damage-percent-remaining": "&e{0}% &aОсталось.", + "this-shop-is-buying": "&aЭтот магазин &dПОКУПАЕТ&a предметы.", + "this-shop-is-selling": "&aЭтот магазин &bПРОДАЕТ&a предметы.", + "effects": "&aЭффекты", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cОбход блокировки QuickShop!", + "that-is-locked": "&cМагазин закрыт.", + "how-many-buy": "&aНапишите в чат сколько предметов вы хотите &bКУПИТЬ&a. Вы можете купить &e {0} &a. Введите &ball&a чтобы купить всё.", + "how-many-sell": "&aНапишите в чат сколько предметов вы хотите &dПРОДАТЬ&a. Доступно: &e{0}&a. Введите &ball&a чтобы продать всё.", + "not-allowed-to-create": "&cВы не можете создать магазин здесь.", + "blacklisted-item": "&cЭтот предмет находится в черном списке. Вы не можете продавать его.", + "how-much-to-trade-for": "&aВведите в чат цену, за которую вы хотите продать &e{0}.", + "command": { + "toggle-unlimited": { + "unlimited": "&aМагазин теперь неограничен", + "limited": "&aМагазин теперь ограничен" + }, + "no-owner-given": "&cВладелец не установлен. Используйте команду &a\/qs setowner &c", + "new-owner": "&aНовый владелец: &e{0}", + "now-buying": "&aЭтот магазин теперь &dПОКУПАЕТ&a &e{0}", + "now-selling": "&aЭтот магазин теперь &bПРОДАЕТ &e{0}", + "cleaning": "&aУдаление пустых магазинов...", + "reloading": "&aПерезагружаю конфигурацию...", + "cleaned": "&aОчищено &e{0}&a магазинов", + "no-type-given": "&cИспользовать: \/qs find <предмет>", + "no-amount-given": "&cСумма не указана. Используйте &a\/qs refill <число>&c", + "now-debuging": "&aУспешно переключены в режим разработчика. Перезагружаю QuickShop...", + "now-nolonger-debuging": "&aУспешно переключены в обычный режим. Перезагружаю QuickShop...", + "wrong-args": "&cПараметры не совпадают, введите \/qs help для получения справки.", + "description": { + "title": "&aQuickShop справка", + "unlimited": "&eСделать магазин бесконечным", + "setowner": "&eСменить владельца магазина", + "owner": "&eСменить владельца магазина", + "buy": "&eПеревести в режим &dПОКУПКА", + "sell": "&eПеревести в режим &dПРОДАЖА", + "price": "&eСменить цену покупки\/продажи вашего магазина", + "clean": "&eУдалить все пустые магазины (0 предметов)", + "find": "&eНаходит ближайший магазин определенного типа.", + "reload": "&aПерезагружаю конфигурацию из config.yml.", + "refill": "&eДобавляет определенное количество предметов в магазин", + "empty": "&eУдаляет все товары из магазина", + "debug": "&eПереключиться в режим разработчика", + "create": "&eСоздает новый магазин из сундука на который вы смотрите", + "fetchmessage": "&eПолучить непрочитанное сообщение", + "info": "&eПоказать статистику QuickShop", + "paste": "&eАвтоматически загружать серверную информацию в Pastebin", + "staff": "&eУправление совладельцами магазина", + "remove": "&eУдалить магазин на который вы смотрите", + "amount": "&eИспользуйте эту команду, чтобы ввести цену или число в случае проблем с вводом данных в чат", + "about": "&eО QuickShop", + "help": "&eПоказать подсказку QuickShop", + "supercreate": "&eСоздать магазин в обход всех проверок защиты" + } + }, + "signs": { + "selling": "Продаёт {0}", + "header": "&c{0}", + "buying": "Покупает {0}", + "item": "{0}", + "price": "{0}", + "unlimited": "Много" + }, + "controlpanel": { + "setowner": "&aВладелец: &b{0} &e[&d&lСменить&e]", + "infomation": "&aПанель управления магазином:", + "setowner-hover": "&eНажмите для смены владельца.", + "unlimited": "&aБесконечный: {0} &e[&d&lПереключить&e]", + "unlimited-hover": "&eНажмите, чтобы переключиться, если магазин БЕСКОНЕЧНЫЙ.", + "mode-selling": "&aРежим: &bПродажа &e[&d&lПереключить&e]", + "mode-selling-hover": "&eНажмите, чтобы переключить магазин в режим покупки.", + "mode-buying": "&aРежим: &bПокупка &e[&d&lПереключить&e]", + "mode-buying-hover": "&eНажмите, чтобы переключить магазин в режим продажи.", + "price": "&aЦена: &b{0} &e[&d&lУстановить&e]", + "price-hover": "&eНажмите для установки новой цены.", + "refill": "&aПополнение: Перезаполнить магазин предметами &e[&d&lOK&e]", + "refill-hover": "&eНажмите чтобы перезаполнить магазин.", + "empty": "&aОчистить: Удалить все предметы в магазине &e[&d&lOK&e]", + "empty-hover": "&eНажмите чтобы очистить магазин.", + "remove": "&c&l[Удалить магазин]", + "remove-hover": "&eНажмите для удаления магазина.", + "commands": { + "setowner": "\/qs setowner [Игрок]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [новая цена]", + "refill": "\/qs refill [количество]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[цена]", + "range": "[диапазон]", + "amount": "[количество]" + }, + "updatenotify": { + "buttontitle": "[Обновить сейчас]", + "onekeybuttontitle": "[Обновление в один клик]", + "list": [ + "{0} уже вышел, Вы используете {1}!", + "Бум! Новое обновление {0} на подходе, Обновитесь!", + "Сюрприз! {0} уже вышел, вы используете {1}", + "Ищите обновление, {0} уже здесь!", + "Ууууупс! {0} вышел, а вы используете {1}!", + "Обновление QS {0}, почему бы не обновиться?", + "Исправление и пере... Извините. {0} обновлен!", + "Ошибка! Нет, не ошибка, просто {0} обновился!", + "ОМГ! {0} уже вышел! Почему вы до сих пор используете {1}?", + "Новость для: Обновление QuickShop {0}!", + "Вы должны обновиться {0}!", + "Обновление {0}, сохраните обновление!", + "Сообщите админу что {0} уже вышел!", + "Посмотрите---{0} обновлен, вы используете {1}", + "Аххххх! Новое обновление {0}! Обновитесь!", + "Чего тут думать? {0} вышел! Обновитесь!" + ], + "remote-disable-warning": "&cЭта версия QS была отключена сервером, это означает что у неё есть серьезные проблемы, подробнее SpigotMC : {0}. Это сообщение будет появляться пока вы не отключите или обновите плагин.", + "label": { + "unstable": "[Не стабильный]", + "stable": "[Стабильный]", + "lts": "[LTS - Долгосрочная стабильная версия]", + "qualityverifyed": "[Качество]", + "github": "[GitHub]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Главная ветка]" + } + }, + "shop-removed-cause-ongoing-fee": "&cВаш магазин на {0} был удален т.к. у вас не достаточно денег чтобы его оплачивать!", + "digits-reach-the-limit": "&cДостигнут лимит количества цифр после запятой.", + "complete": "&aВыполнено!", + "quickshop-gui-preview": "Предосмотр вещи QuickShop", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/sr-SP/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/sr-SP/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/sr-SP/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/sv-SE/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/sv-SE/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/sv-SE/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/tr-TR/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/tr-TR/messages.json new file mode 100644 index 0000000..5f03965 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/tr-TR/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Çevirmen: NOYB, DazzGranto", + "translation-version": "Destek Versiyonu: Reremake", + "translation-contributors": "Katkıda Bulunanlar: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Dil Bölgesi: Türkçe (tr_TR)", + "language-version": "31", + "not-looking-at-shop": "&cQuickShop bulunamadı, birine bakıyor olmalısın.", + "no-anythings-in-your-hand": "&cElinde hiçbir şey yok.", + "no-permission": "&cBunu yapmaya iznin yok.", + "3rd-plugin-build-check-failed": "Üçüncü parti bir eklenti yetki kontrolünü reddetti, orada yetkiniz var mıydı?", + "no-creative-break": "&cYaratıcı modda başka oyuncuların marketlerini kıramazsınız, hayatta kalma moduna geçiniz veya yerine supertool {0} aletini kullanmayı deneyin.", + "trading-in-creative-mode-is-disabled": "&cYaratıcı modda marketlerle ticaret yapamazsınız.", + "supertool-is-disabled": "&cSupertool kapalı, hiçbir marketi kıramazsınız.", + "no-double-chests": "&cÇifte sandık ile market oluşturamazsınız.", + "not-managed-shop": "&cBu marketin sahibi ya da moderatörü değilsin", + "shop-already-owned": "&cBu zaten bir market.", + "chest-was-removed": "&cSandık kaldırıldı.", + "price-too-cheap": "&cFiyat &e${0}&c'dan büyük olmalıdır.", + "no-price-change": "&cBu bir fiyat değişikliğine sebep olmaz.", + "you-cant-afford-a-new-shop": "&cYeni bir market oluşturma maliyeti: ${0}", + "player-bought-from-your-store-tax": "&c{0} marketinden {1} tane {2} satın aldı ve sana karşılığında {3} ödedi.", + "you-cant-afford-to-change-price": "&cMarketinizin fiyatını değiştirmek ${0} tutarındadır.", + "success-created-shop": "&aMarket oluşturuldu.", + "success-removed-shop": "&aMarket kaldırıldı.", + "shops-arent-locked": "&cUnutmayın! Marketler hırsızlara karşı koruma altında DEĞİLDİR. Eğer marketleri korumak istiyorsanız LWC, Lockette, vb. eklentiler ile kilitleyiniz.", + "shop-creation-cancelled": "&cMarket oluşturma iptal edildi.", + "shop-purchase-cancelled": "&cMarket satın alma işlemi iptal edildi.", + "shop-stock-too-low": "&cMarkette sadece {0} tane {1} var", + "you-cant-afford-to-buy": "&cBu ${0}'a mâl oluyor ama sende ${1} var.", + "negative-amount": "&cSaf! Negatif miktarlarda işlem yapamazsın.", + "not-a-number": "&cYalnızca sayı kullanabilirsiniz ama siz {0} girdiniz.", + "not-a-integer": "&cYalnızca tamsayı olabilir ama siz {0} girdiniz.", + "player-bought-from-your-store": "&c{0} marketinden {1} tane {2} satın aldı.", + "shop-out-of-stock": "&5{0},{1},{2}'deki marketinizde {3} tükendi", + "shop-has-no-space": "&cDükkanda sadece {0} için daha fazla {1} yer var.", + "you-dont-have-that-many-items": "&cSende sadece {0} tane {1} var.", + "the-owner-cant-afford-to-buy-from-you": "&cBu {0} ediyor ama sende {1} var", + "player-sold-to-your-store": "&a{0} marketine {1} tane {2} sattı.", + "shop-out-of-space": "&5{0},{1},{2}'deki marketin doldu.", + "fee-charged-for-price-change": "&aFiyatı değiştirmek için &c{0}&a ödemelisin.", + "price-is-now": "&aMarketin yeni fiyatı &e{0}", + "thats-not-a-number": "&cGeçersiz sayı", + "no-price-given": "&cLütfen geçerli bir fiyat verin.", + "average-price-nearby": "&aYakındaki Ortalama Fiyat: &e${0}", + "shop-has-changed": "&cKullanmaya çalıştığınız market, tıkladığınızdan beri değişti.", + "shop-not-exist": "&cOrada market yok.", + "nearby-shop-this-way": "&aMarket sizden {0} blok uzakta.", + "no-nearby-shop": "&cYakında {0} ile eşleşen market yok.", + "buying-more-than-selling": "&cUYARI: Sattığınızdan fazla ürün satın alıyorsunuz.", + "not-enough-space": "&cSadece {0} tane daha yeriniz kaldı.", + "refill-success": "&aDoldurma işlemi başarılı", + "empty-success": "&aBoşaltma işlemi başarılı", + "admin-shop": "AdminMarketi", + "unknown-owner": "Bilinmiyor", + "owner-bypass-check": "&eTüm kontroller atlandı, Ticaret başarılı! (Market sahibisiniz)", + "reached-maximum-can-create": "&cZaten maksimum {0}\/{1} market oluşturdunuz!", + "restricted-prices": "&c{0} için sınırlandırılmış fiyatlar: min {1}, maks {2}", + "no-enough-money-to-keep-shops": "&cMarketlerini tutacak kadar paran yoktu! Bütün marketlerin kaldırıldı...", + "nothing-to-flush": "&aYeni market mesajınız yok.", + "break-shop-use-supertool": "&eSuperTool aletini kullanarak marketleri kırabilirsin.", + "failed-to-put-sign": "&cMarket çevresinde bilgi tabelasını yerleştirmek için yeterli yer yok.", + "failed-to-paste": "&cVeriler Pastebin'e yüklenemedi, internetinizi kontrol edip tekrar deneyiniz. (Ayrıntılar için konsola bakın)", + "warn-to-paste": "&eVeriler toplanıyor ve Pastebin'e yükleniyor, bu biraz zaman alabilir. &c&lUyarı&c, Veriler bir hafta boyunca herkese açık tutulur, sunucu konfigürasyonunuzu ve diğer hassas bilgilerinizi sızdırabilir, sadece &lgüvendiğiniz personele\/geliştiriciye &c göderdiğinizden emin olun.", + "price-too-high": "&cMarket fiyatı çok yüksek! {0} fiyatından yüksek bir tane oluşturamazsınız.", + "you-cant-create-shop-in-there": "&cBurada bir market oluşturma izniniz yok.", + "unknown-player": "&cHedef oyuncu mevcut değil, lütfen yazdığınız kullanıcı adını kontrol ediniz.", + "shop-staff-cleared": "&aBaşarıyla marketinizin bütün personeli kadırıldı.", + "shop-staff-added": "&a{0} başarıyla market personellerine eklendi.", + "shop-staff-deleted": "&a{0} başarıyla market personellerinizden çıkarıldı.", + "no-permission-build": "&cBurada bir market yapamazsınız.", + "success-change-owner-to-server": "&aMarket sahibi başarıyla Server yapıldı.", + "flush-finished": "&aMesajlar başarıyla temizlendi.", + "purchase-failed": "&cSatın alma başarısız oldu: İç Hata, lütfen sunucu bir sunucu yöneticisine başvurun.", + "no-pending-action": "&cBekleyen bir işleminiz yok", + "permission-denied-3rd-party": "&cİzin reddedildi: 3. taraf eklenti [{0}].", + "menu": { + "successful-purchase": "&aBaşarıyla Satın Alındı:", + "successfully-sold": "&aBaşarıyla Satıldı:", + "item-name-and-price": "&e{0} tane {1} &aiçin &e{2}", + "sell-tax": "&aVergilerde &e{0} &aödediniz.", + "sell-tax-self": "&aBu marketin sahibi oldğun için vergi ödemiyorsun.", + "enchants": "&5Büyüler", + "stored-enchants": "&5Depolanmış Büyüler", + "shop-information": "&aMarket Bilgisi:", + "owner": "&aSahibi: {0}", + "item": "&aÖğe: &e{0}", + "preview": "&b[Öğeyi Önizle]", + "space": "&aYer: &e{0}", + "stock": "&aStok &e{0}", + "price-per": "&e{0} &abaşına &e{1}", + "total-value-of-chest": "&aSandığın toplam değeri: &e{0}", + "damage-percent-remaining": "&aKalan &e{0}%.", + "this-shop-is-buying": "&aBu market eşya %dSATIN ALIYOR&a.", + "this-shop-is-selling": "&aBu market eşya %SATIYOR&a.", + "effects": "&aEfektler", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBir QuickShop kilidi atlanıyor!", + "that-is-locked": "&cBu market kilitli.", + "how-many-buy": "&aNe kadar &bSATIN ALMAK&a istediğini sohbete yaz. &e{0}&a tane satın alabilirsiniz. Hepsini satın almak için &ball&a yaz.", + "how-many-sell": "&aNe kadar &bSATMAK&a istediğini sohbete yaz. &e{0}&a tane satabilirsiniz. Hepsini satmak için &ball&a yaz.", + "not-allowed-to-create": "&cBurada bir market oluşturamazsın.", + "blacklisted-item": "&cBu eşya kara listede. Onu satamazsın", + "how-much-to-trade-for": "&e{0}&a eşyasından kaç tane ticaret yapmak istediğini sohbete yaz.", + "command": { + "toggle-unlimited": { + "unlimited": "&aMarket şimdi sınırsız", + "limited": "&aMarket şimdi sınırlı" + }, + "no-owner-given": "&cSahip belirlenmemiş. &a\/qs setowner &c komudunu kullan", + "new-owner": "&aYeni sahip: &e{0}", + "now-buying": "&aŞimdi &e{0} &dSATIN ALINIYOR&a", + "now-selling": "&aŞimdi &e{0} &dSATILIYOR&a", + "cleaning": "&aStoku 0 olan marketler temizleniyor...", + "reloading": "&aYeniden Yükleniyor...", + "cleaned": "&e{0} &a tane market temizlendi", + "no-type-given": "&cKullanım: \/qs find ", + "no-amount-given": "&cMiktar belirtilmemiş. &a\/qs refill &ckomutunu kullan", + "now-debuging": "&aBaşarıyla geliştirici moduna geçildi, QuickShop yeniden yükleniyor...", + "now-nolonger-debuging": "&aBaşarıyla üretim moduna geçildi, QuickShop yeniden yükleniyor...", + "wrong-args": "&cParametreler uyşmuyor, yardım için &a\/qs help&c komudunu kullan", + "description": { + "title": "&aQuickShop Yardım", + "unlimited": "&eBir marketi sınırsız yapar", + "setowner": "&eMarket sahibini değiştirir", + "owner": "&eMarket sahibini değiştirir", + "buy": "&eBir marketi &dSATIN ALMA&e moduna geçirir", + "sell": "&eBir marketi &dSATMA&e moduna geçirir", + "price": "&eBir marketinizin alım\/satım fiyatını değiştirir", + "clean": "&eBütün (yüklü) 0 stoklu marketleri kaldırır", + "find": "&eBelirli bir türde en yakındaki marketi bulur.", + "reload": "&eQuickShop için config.yml dosyasını yeniden yükler", + "refill": "&eBir mağazaya belirli sayıda öğe ekler", + "empty": "&eBir marketteki bütün stokları kaldırır", + "debug": "%eGeliştirici moduna geç", + "create": "&eHedef sandıkta bir market oluşturur", + "fetchmessage": "&eOkunmamış market mesajını al", + "info": "&eQuickShop İstatistiklerini Göster", + "paste": "&eSunucu verilerini Pastebin'e otomatik yükle", + "staff": "&eMağaza personellerinizi yönetin", + "remove": "&eBaktığınız marketi kaldırın", + "amount": "&eİşlemlerinizi tutarla gerçekleştirin(sohbet eklentisi konuları için)", + "about": "&eQuickShop hakkındayı Göster", + "help": "&eQuickShop yardımlarını Göster", + "supercreate": "%eBütün koruma kontrollerini atlayarak bir market oluştur" + } + }, + "signs": { + "selling": "Satış {0}", + "header": "&c{0}", + "buying": "Alış {0}", + "item": "{0}", + "price": "her biri {0}", + "unlimited": "Sınırsız" + }, + "controlpanel": { + "setowner": "&aSahhibi: &b{0} &e[&d&lDeğiştir&e]", + "infomation": "&aMarket Kontrol Paneli:", + "setowner-hover": "&eSahibi değiştirmek için tıkla.", + "unlimited": "&aSınırsız: {0} &e[&d&lDeğiştir&e]", + "unlimited-hover": "&eMağaza sınırsızsa geçiş yapmak için tıkla.", + "mode-selling": "&aMarket Modu: &bSatma &e[&d&lDeğiştir&e]", + "mode-selling-hover": "&eMarketi satın alma moduna geçirmek için tıkla.", + "mode-buying": "&aMarket Modu: &bSatın Alma &e[&d&lDeğiştir&e]", + "mode-buying-hover": "&eMarketi satma moduna geçirmek için tıkla.", + "price": "&aFiyat: &b{0} &e[&d&lBelirle&e]", + "price-hover": "&eMarket için yeni bir fiyat belirlemek için tıkla.", + "refill": "&aDoldur: Market itemlerini doldur &e[&d&lTamam&e]", + "refill-hover": "&eMarketi doldurmak için tıkla.", + "empty": "&aBoşalt: Marketteki bütün öğeleri kaldır &e[&d&lTamam&e]", + "empty-hover": "%eMarketin envanterini temizlemek için tıkla.", + "remove": "&c&l[Marketi Kaldır]", + "remove-hover": "&eBu marketi kaldırmak için tıkla.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Şimdi Güncelle]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} yayınlandı, Sen hala {1} versiyonunu kullanıyorsun!", + "Boom! Yeni güncelleme {0} geliyor, Güncelle!", + "Sürpriz! {0} geldi, sen {1} kullanıyorsun", + "Görünüşe göre güncellemen gerekiyor, {0} yayınlandı!", + "Ooops! {0} yayınlandı, sen {1} kullanıyorsun!", + "Söz veriyorum, QS {0} versiyonuna güncellendi, neden hala güncellemedin?", + "Tamir ediliyor ve ona... Üzgünüm {0} yayınlandı!", + "Err! Yok, bu bir hata değil, {0} yayınlandı!", + "OMG! {0} Çıktı! Neden hala {1} versiyonunu kullanıyorsun?", + "Bügünün Haberleri: QuickShop {0} versiyonuna güncellendi!", + "Eklenti K.I.A, {0} versiyonuna güncellemelisin!", + "Fuze {0} güncellemesini bulanıklaştırıyor, güncellemeyi kaydet!", + "Bir güncelleme var komutanım, {0} şuan çıktı!", + "Tarzıma bak---{0} güncellendi, sen hala {1} versiyonunu kullanıyorsun", + "Ahhhhhhh! Yeni güncelleme {0}! Güncelle!", + "Ne Düşünüyorsun? {0} yayınlandı! Güncelle!" + ], + "remote-disable-warning": "&cQuickShop'un bu sürümü uzak sunucu tarafından devre dışı olarak işaretlendi, bunun anlamı bu versiyonda büyük problemler oluşabilir, detayları SpigotMC sayfamızdan edinin: {0}. Bu uyarı siz bu versiyonu devre dışı bırakılmamış başka bir versiyon ile değiştirmedikçe konsolda belirecek ve spam yapacak, sunucu hızınızı etkilemez.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&c{0} koordinatlarında bulunan marketiniz açık tutacak kadar paranız olmadığı için kaldırılmıştır!", + "digits-reach-the-limit": "&cFiyattaki basamak sınırına ulaştınız.", + "complete": "&aTamamlandı!", + "quickshop-gui-preview": "QuickShop GUI Önizleme Öğesi", + "shops-recovering": "Dükkanlar yedekten kurtarılıyor...", + "shops-backingup": "Mağazalar veritabanından yedekleniyor... ", + "saved-to-path": "Yedek dosyası {0} klasörüne kaydedildi.", + "backup-failed": "Veritabanı yedeklenemiyor, ayrıntılar için konsolu kontrol edin.", + "translate-not-completed-yet-click": "{0} dilinin çevirisi {1} tamamlandı, çeviriyi geliştirmemize yardımcı olmak ister misiniz? Buraya Tıkla!", + "translate-not-completed-yet-url": "{0} dilinin çevirisi {1} tamamlandı, çeviriyi geliştirmemize yardımcı olmak ister misiniz? Göz atın: {2}", + "language-info-panel": { + "name": "Dil: ", + "code": "Kod: ", + "progress": "İlerleme: ", + "help": "Bize Yardım Edin: ", + "translate-on-crowdin": "[Crowdin'de Çevirin]]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/uk-UA/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/uk-UA/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/uk-UA/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/vi-VN/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/vi-VN/messages.json new file mode 100644 index 0000000..ce11e44 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/vi-VN/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "31", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "3rd-plugin-build-check-failed": "Some 3rd party plugin denied the permission checks, did you have permission built in there?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "not-managed-shop": "&cYou are not the owner or moderator of the shop", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!", + "quickshop-gui-preview": "QuickShop GUI Preview Item", + "shops-recovering": "Recovering shops from backup...", + "shops-backingup": "Backing up the shops from database... ", + "saved-to-path": "The backup file was saved to {0} .", + "backup-failed": "Cannot backup the database, check the console for details.", + "translate-not-completed-yet-click": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Click Here!", + "translate-not-completed-yet-url": "The translation of language {0} has completed {1}, Do you want help us to improve the translation? Browse: {2}", + "language-info-panel": { + "name": "Language: ", + "code": "Code: ", + "progress": "Progress: ", + "help": "Help Us: ", + "translate-on-crowdin": "[Translate on Crowdin]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/zh-CN/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/zh-CN/messages.json new file mode 100644 index 0000000..ae43d10 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/zh-CN/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "翻译者:&b&lMashirl happyvalley yzhh You_wen sandtechnology", + "translation-version": "支持版本:Reremake", + "translation-contributors": "开发贡献者:Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "本地化语言:简体中文 (zh_CN)", + "language-version": "31", + "not-looking-at-shop": "&c没有找到商店, 你必须选中箱子才行。", + "no-anythings-in-your-hand": "&c你的手里没有任何物品。", + "no-permission": "&c你没有权限这样做。", + "3rd-plugin-build-check-failed": "权限检查被拒绝访问,你没有建立的权限", + "no-creative-break": "&c你不能在创造模式破坏其他玩家的商店, 请使用生存模式或用超级工具 {0} 来破坏.", + "trading-in-creative-mode-is-disabled": "&c你不能在创造模式下使用商店交易.", + "supertool-is-disabled": "&c超级工具已被禁用,现已不能使用超级工具破坏任何商店.", + "no-double-chests": "&c你没有权限创建大箱子商店。", + "not-managed-shop": "&c你不是该商店的所有者或管理者", + "shop-already-owned": "&c这已经是一个商店了。", + "chest-was-removed": "&c当前箱子已被移除。", + "price-too-cheap": "&c价格必须大于&e${0}", + "no-price-change": "&c这不会导致价格变动!", + "you-cant-afford-a-new-shop": "&c你需要 {0} 才能创建一个商店。", + "player-bought-from-your-store-tax": "&c{0} 从你的商店购买了 {1} {2},缴纳了{3}的税。", + "you-cant-afford-to-change-price": "&c你需要 {0} 才能修改商店的价格。", + "success-created-shop": "&a创建商店成功!", + "success-removed-shop": "&a商店已删除!", + "shops-arent-locked": "&c注意,商店无法防盗,如果您想要防盗功能,请使用Lockette,LWC,等插件锁住箱子。", + "shop-creation-cancelled": "&c已取消创建商店。", + "shop-purchase-cancelled": "&c已取消购买。", + "shop-stock-too-low": "&c这个商店只有 {0} 个 {1} 了。", + "you-cant-afford-to-buy": "&c余额不足!购买该商店物品需要 {0},但是你只有 {1}。", + "negative-amount": "&c哎呀,你输入的是个负数呀!", + "not-a-number": "&c这里只能输入数字,但是您输入的是 {0}", + "not-a-integer": "&c这里只能输入数字,但是您输入的是 {0}", + "player-bought-from-your-store": "&c{0} 在你的商店购买了 {1} 个 {2} 。", + "shop-out-of-stock": "&5你位于 {0}, {1}, {2},的商店的 {3} 库存已经没有了。", + "shop-has-no-space": "&c这个商店只能装下 {0} 个 {1} 了。", + "you-dont-have-that-many-items": "&c你只有 {0} 个 {1}。", + "the-owner-cant-afford-to-buy-from-you": "&c这件商品标价 {0},但是店主只剩 {1} 了。", + "player-sold-to-your-store": "&a{0} 在你的商店出售了 {1} 个 {2} 。", + "shop-out-of-space": "&5你位于 {0}, {1}, {2},的商店库存爆仓了。", + "fee-charged-for-price-change": "&a你花了 &c{0}&a 修改了价格。", + "price-is-now": "&a新价格是 &e{0} 。", + "thats-not-a-number": "&c无效数字。", + "no-price-given": "&c请输入一个有效的价格。", + "average-price-nearby": "&a附近平均价格: &e{0}", + "shop-has-changed": "&c商店在你尝试使用的时候发生了更改从你点击他的时候起", + "shop-not-exist": "&c这里没有商店", + "nearby-shop-this-way": "&a商店距离你 {0} 格远", + "no-nearby-shop": "&c周围没有与 {0} 匹配的商店", + "buying-more-than-selling": "&c警告:你买的东西比你卖的多!", + "not-enough-space": "&c此商店空间不足,剩余 {0}", + "refill-success": "&a重填成功", + "empty-success": "&a清空成功", + "admin-shop": "系统商店", + "unknown-owner": "未知", + "owner-bypass-check": "&e绕过所有检查,交易已完成(你是商店所有者)", + "reached-maximum-can-create": "&c你创建的商店数量达到上限{0}\/{1}", + "restricted-prices": "&c物品{0}价格收到限制:最小 {1},最大{2}", + "no-enough-money-to-keep-shops": "&c你没有足够的金钱去维持你的商店!所有商店已被移除...", + "nothing-to-flush": "&a你没有新的商店消息", + "break-shop-use-supertool": "&e你可以使用SuperTool来破坏商店", + "failed-to-put-sign": "&c商店没有足够的空间放置信息牌。", + "failed-to-paste": "&c数据上传到Pastebin失败,检查你的网络并重试。(查看后台获取详情)", + "warn-to-paste": "&e收集并上传数据到Pastebin,这会花费点时间。&c&l警告&c,数据将会在一周内对外可见,可能会导致你泄露服务器的配置和其他敏感信息,确保只向&l你信任的人\/开发者&c发送链接。", + "price-too-high": "&c商品的价格太高了!你不能创建高于 {0} 的商店。", + "you-cant-create-shop-in-there": "&c你没有在这个位置创建商店的权限。", + "unknown-player": "&c目标玩家不存在,请检查你输入的玩家名字。", + "shop-staff-cleared": "&a成功从你的商店移除所有助手任意", + "shop-staff-added": "&a成功添加 {0} 到你的商店的助手中", + "shop-staff-deleted": "&a成功从你的商店的助手中移除 {0}", + "no-permission-build": "&c你不能在这里建立商店。", + "success-change-owner-to-server": "&a成功设置商店所有者为 服务器", + "flush-finished": "&a成功获取所有商店记录", + "purchase-failed": "&c支付失败:内部错误,请联系服务器管理员", + "no-pending-action": "&c你没有任何进行中的操作", + "permission-denied-3rd-party": "&c没有权限:第三方插件 [{0}]。", + "menu": { + "successful-purchase": "&a成功支付:", + "successfully-sold": "&a成功出售:", + "item-name-and-price": "&e{0} {1} &a每 &e{2}", + "sell-tax": "&a你支付了&e{0}&a的税。", + "sell-tax-self": "&a你是这个商店的主人所以不用交税。", + "enchants": "&5附魔", + "stored-enchants": "&5附魔", + "shop-information": "&a商店信息:", + "owner": "&a所有者:{0}", + "item": "&a物品:&e{0}", + "preview": "&b[物品预览]", + "space": "&a空间: &e{0}", + "stock": "&a库存&e{0}", + "price-per": "&a每&e{0}&a价格&e{1}", + "total-value-of-chest": "&a共计商店数: &e{0}", + "damage-percent-remaining": "&e{0}% &a剩余", + "this-shop-is-buying": "&a这个商店&d收购&a物品。", + "this-shop-is-selling": "&a这个商店&d出售&a物品。", + "effects": "&a效果", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&c你绕过了QuickShop的锁!", + "that-is-locked": "&c这个商店已上锁。", + "how-many-buy": "&a在聊天栏中输入想 &b购买 &a的数量", + "how-many-sell": "&a在聊天栏中输入想 &d出售 &a的数量. 你有还有 &e{0} &a物品", + "not-allowed-to-create": "&c你不能在这里创建商店", + "blacklisted-item": "&c此物品位于黑名单中,你不可以出售它", + "how-much-to-trade-for": "&a输入每个 &e{0} &a的价格", + "command": { + "toggle-unlimited": { + "unlimited": "&a商店现在是无限的。", + "limited": "&a商店现在是有限的。" + }, + "no-owner-given": "&c未指定新的所有者. 使用 &a\/qs owner <新的店主>&c", + "new-owner": "&a新的商店所有者: &e{0}", + "now-buying": "&a现在 &d收购中 &e{0}", + "now-selling": "&a现在 &b出售中 &e{0}", + "cleaning": "&c正在清理脱销商店...", + "reloading": "&a重载中", + "cleaned": "&a清理了 &e{0} &a个商店", + "no-type-given": "&c用法: \/qs find <物品名称>", + "no-amount-given": "&c数量未指定. 使用 &a\/qs refull <数量>&c", + "now-debuging": "&a成功切换到了开发者模式,插件重载中...", + "now-nolonger-debuging": "&a成功切换到了生产环境模式,插件重载中...", + "wrong-args": "&c参数不匹配,使用\/qs help来查看帮助", + "description": { + "title": "&aQuickShop 帮助", + "unlimited": "&e切换商店到无限模式", + "setowner": "&e为商店设置新的所有者。", + "owner": "&e为商店设置新店主", + "buy": "&e切换到 &d收购 &e模式", + "sell": "&e切换到 &b出售 &e模式", + "price": "&e修改 收购\/出售 的价格", + "clean": "&e移除所有已加载的脱销的商店", + "find": "&e寻找附近匹配你的物品名称的商店", + "reload": "&e为 QuickShop 重载 config.yml", + "refill": "&e添加一定数量的物品到商店", + "empty": "&e清空商店库存", + "debug": "&e切换到开发者模式", + "create": "&e将目标箱子设置为商店", + "fetchmessage": "&e获取未读商店日志", + "info": "&e查看QuickShop统计信息", + "paste": "&e上传调试信息到Patebin", + "staff": "&e管理商店助手", + "remove": "&e移除你选中的的商店", + "amount": "&e以指定数量执行你进行中的操作(用于解决聊天插件带来的不兼容问题)", + "about": "&e关于QuickShop", + "help": "&e显示QuickShop帮助", + "supercreate": "&e越过所有区域保护检查创建商店" + } + }, + "signs": { + "selling": "出售 {0}", + "header": "&c{0}", + "buying": "收购 {0}", + "item": "{0}", + "price": "单价:{0}", + "unlimited": "无限" + }, + "controlpanel": { + "setowner": "&a所有者: &b{0} &e[&d&l修改&e]", + "infomation": "&a商店控制面板", + "setowner-hover": "&e点击来修改店主", + "unlimited": "&a无限模式: {0} &e[&d&l切换&e]", + "unlimited-hover": "&e点击切换商店是否为无限模式", + "mode-selling": "&a商店模式: &b出售 &e[&d&l开关&e]", + "mode-selling-hover": "&e点击更换销售模式。", + "mode-buying": "&a商店模式: &b收购 &e[&d&l更改&e]", + "mode-buying-hover": "&e点击更换销售模式。", + "price": "&a价格: &b{0} &e[&d&l设定&e]", + "price-hover": "&e点击来给商店设置一个新的价格", + "refill": "&a填充: 重新填充商品 &e[&d&l确认&e]", + "refill-hover": "&e点击重新填充商品", + "empty": "&a清空: 删除商店所有商品 &e[&d&l确认&e]", + "empty-hover": "&e点击清除商店库存", + "remove": "&c&l[删除商店]", + "remove-hover": "&e点击来删除商店", + "commands": { + "setowner": "\/qs setowner [玩家id]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [修改后的新价格]", + "refill": "\/qs refill [补货数量]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a√", + "failed": "&c×" + }, + "tabcomplete": { + "price": "[价格]", + "range": "[范围]", + "amount": "[数量]" + }, + "updatenotify": { + "buttontitle": "[立即更新]", + "onekeybuttontitle": "[一键升级]", + "list": [ + "{0} 版本已经发布,您还在使用{1}", + "噔噔咚!新版本{0} 已经发布,快升级!", + "在?{0} 来了,你还在使用{1}", + "看起来你需要更新了,{0} 版本已经发布了!", + "噢!{0}已经发布了呀,你还在用 {1}!", + "我保证,QS已经升级到了 {0},你为什么没有升级?", + "修复并更新了...抱歉其实是{0}版本已经发布!", + "错误!其实并没有错误,只是 {0} 版本已经发布了!", + "哦买噶!{0}已经出了呀!你为什么还在用 {1}?", + "今日新闻:QuickShop已经更新至 {0} !", + "插件确认已阵亡,你现在应该升级插件到 {0} !", + "进攻方正在进攻更新 {0},救救更新吧!", + "这里是升级指挥官,{0}版本刚刚发布了!", + "看我的Style→{0} 出了, 你为什么还在用 {1}呢?", + "啊啊啊啊啊啊啊啊啊啊!更新 {0} 来了!快升级!", + "你在想什么呢?{0}已经发布了!快更新!" + ], + "remote-disable-warning": "&c这个版本的QuickShop已经被远程服务器停用了,这意味着这个版本的QS可能存在着严重的问题,请在我们的SpigotMC插件页面:{0}里寻找详细信息。这个警告会出现按并且在你的控制台上通知直到你使用其他没有被停用的版本来替换这个版本,停用后不影响您的服务器的正常运行。", + "label": { + "unstable": "[不稳定]", + "stable": "[稳定]", + "lts": "[长期服务]", + "qualityverifyed": "[质量]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[主分支]" + } + }, + "shop-removed-cause-ongoing-fee": "&c你在 {0} 的商店已经被移除了,因为你没有足够的资金去维持它!", + "digits-reach-the-limit": "&c你输入的价格小数点后面的数字已经达到了极限。", + "complete": "&a完成!", + "quickshop-gui-preview": "QuickShop GUI预览商品", + "shops-recovering": "正在从备份中恢复商店...", + "shops-backingup": "正在备份数据库中的商店... ", + "saved-to-path": "备份文件已保存到 {0}。", + "backup-failed": "无法备份数据库,请查看控制台以获取详细信息。", + "translate-not-completed-yet-click": "{0} 的翻译完成度为 {1},您想帮助我们改进翻译吗?点击这里!", + "translate-not-completed-yet-url": "{0} 的翻译完成度为 {1},您想帮助我们改进翻译吗?来这里吧: {2}", + "language-info-panel": { + "name": "语言:", + "code": "语言代码:", + "progress": "进度:", + "help": "帮助我们: ", + "translate-on-crowdin": "[在 Crowdin 上翻译]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/zh-TW/messages.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/zh-TW/messages.json new file mode 100644 index 0000000..a4f2c6b --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/lang/zh-TW/messages.json @@ -0,0 +1,252 @@ +{ + "translation-author": "譯師: &b&lmoontai0724 & Tsuna & 音樂 & NathanTW", + "translation-version": "支援版本: Reremake", + "translation-contributors": "協作者: Timtower, Netherfoam, KaiNoMood, Mgazul 和Andre_601", + "translation-country": "語言: &b&l繁體中文 Chinese Traditional (zh_TW)", + "language-version": "31", + "not-looking-at-shop": "&c沒有找到商店, 您必須看著一個商店!", + "no-anythings-in-your-hand": "&c您的手中是空的。", + "no-permission": "&c您沒有權限執行這個指令。", + "3rd-plugin-build-check-failed": "看來你的權限插件似乎拒絕了QuickShop檢查玩家的權限,你是否該設定一下?", + "no-creative-break": "&cYou cannot break other players shops in the creative mode, switch to survival mode or try to use supertool {0} instead.", + "trading-in-creative-mode-is-disabled": "&cYou cannot trade with shop in the creative mode.", + "supertool-is-disabled": "&cSupertool is disabled, cannot break any shop.", + "no-double-chests": "&c您無法創建一個大箱子商店 (兩個箱子組成的大箱子)。", + "not-managed-shop": "你沒有權限管理此商店", + "shop-already-owned": "&c這已經是個商店了。", + "chest-was-removed": "&c箱子已被移除。", + "price-too-cheap": "&c價格必須大於 &e${0}", + "no-price-change": "&c價格並沒有變更!", + "you-cant-afford-a-new-shop": "&c需要花費 {0} 元才能創建商店!", + "player-bought-from-your-store-tax": "&c{0} 從您的商店買了 {1} 個 {2}, 同時您被收取 {3} 元的稅金。", + "you-cant-afford-to-change-price": "&c您需要花費 {0} 元來更改商品價格。", + "success-created-shop": "&a成功創建商店!!!", + "success-removed-shop": "&a已經移除商店。", + "shops-arent-locked": "&c請注意,商店並沒有保護箱子! 若您想要避免被偷,請用鎖箱插件將箱子鎖上!", + "shop-creation-cancelled": "&c已經取消創建商店。", + "shop-purchase-cancelled": "&c已經取消購買。", + "shop-stock-too-low": "&c這個商店只剩 {0} 個 {1}。", + "you-cant-afford-to-buy": "&c商品價格是 {0} 元, 但是您只有 {1} 元。", + "negative-amount": "&c我的天啊, 沒想到居然有人想要交易負數的數量!", + "not-a-number": "&c輸入只能是數字, 但您輸入了 {0}。", + "not-a-integer": "&c輸入只能是整數, 但您輸入了 {0}。", + "player-bought-from-your-store": "&c{0} 從您的商店買了 {1} 個 {2}。", + "shop-out-of-stock": "&5您在 {0}, {1}, {2} 販賣 {3} 的商店已經售鑿一空!", + "shop-has-no-space": "&c這個商店只能再收購 {0} 個 {1} 而已!", + "you-dont-have-that-many-items": "&c您的身上只有 {0} 個 {1}!", + "the-owner-cant-afford-to-buy-from-you": "&c這樣總共是 {0} 元, 但是店主只有 {1} 元。", + "player-sold-to-your-store": "&a{0} 賣了 {1} 個 {2} 給您。", + "shop-out-of-space": "&5您在 {0}, {1}, {2} 的商店現在已經滿了!", + "fee-charged-for-price-change": "&a您付了 &c{0}&a 元以更改商店價格。", + "price-is-now": "&a現在您商店的定價是 &e{0} 元。", + "thats-not-a-number": "&c無效的數字", + "no-price-given": "&c請提供一個有效的價格!", + "average-price-nearby": "&a附近商店的平均價格為: &e{0} 元。", + "shop-has-changed": "&c您嘗試交易的商店在您點擊後已經有變動!", + "shop-not-exist": "&c沒有找到商店。", + "nearby-shop-this-way": "&a這個商店離您有 {0} 格的距離。", + "no-nearby-shop": "&c附近沒有任何 {0} 的商店。", + "buying-more-than-selling": "&c提醒: 您的收購價格比販賣價格高!", + "not-enough-space": "&c您只剩下 {0} 格空間可以裝東西!", + "refill-success": "&a補貨成功!", + "empty-success": "&a清空商品成功!", + "admin-shop": "管理員商店", + "unknown-owner": "未知", + "owner-bypass-check": "&e略過了所有檢查, 交易已經成功! (您是店主)。", + "reached-maximum-can-create": "&c您已經創建了 {0}\/{1} 個商店!", + "restricted-prices": "&c{0} 元是無效的價格: 最高 {1} 元, 最低 {2} 元。", + "no-enough-money-to-keep-shops": "&c您的錢不夠繳稅, 所以您的所有商店已被刪除...", + "nothing-to-flush": "&a沒有關於商店的新消息。", + "break-shop-use-supertool": "&e您可以使用超級工具破壞商店。", + "failed-to-put-sign": "&c您的商店周圍沒有足夠的空間可以放商店的資訊告示牌。", + "failed-to-paste": "&c無法將資料上傳至 Pastebin, 請檢查您的網絡再重試。(詳見控制台)", + "warn-to-paste": "&e正在收集資料並上傳到 Pastebin, 這可能需要一段時間。&c&l警告! &c資料上傳後將保留一週,可能會包含您的伺服器設定與其他敏感資訊,請確認您只將連結傳給您&l信任的工作人員或是開發人員。", + "price-too-high": "&c商店價格有點太高了! 請設定在 {0} 以內。", + "you-cant-create-shop-in-there": "&c您沒有在這個地方創建商店的權限。", + "unknown-player": "&c玩家不存在, 請檢查您輸入的玩家名稱!", + "shop-staff-cleared": "&c已經將所有店員從您的商店移除!", + "shop-staff-added": "&a成功新增 {0} 為您的店員!", + "shop-staff-deleted": "&a已經從店員中移除 {0}。", + "no-permission-build": "&c您無法在這邊創建商店。", + "success-change-owner-to-server": "&a成功將商店擁有者轉交給伺服器!", + "flush-finished": "&a已經成功更新訊息。", + "purchase-failed": "&c交易失敗: 發生錯誤, 請聯繫管理員。", + "no-pending-action": "&c您沒有待處理的操作", + "permission-denied-3rd-party": "&c存取被拒: 第三方插件 [{0}]。", + "menu": { + "successful-purchase": "&a成功購買: ", + "successfully-sold": "&a成功賣出: ", + "item-name-and-price": "&a共 &e{2} &a元的 &e{0} &a個 &e{1}", + "sell-tax": "&a您付了 &e{0} &a元的稅。", + "sell-tax-self": "&a賣給自己的商店不需要繳稅。", + "enchants": "&5附魔", + "stored-enchants": "&5已經有的附魔", + "shop-information": "&a商店資訊: ", + "owner": "&a商店主人: {0}", + "item": "&a商品: &e{0}", + "preview": "&b[預覽商品]", + "space": "&a空間: &e{0}", + "stock": "&a庫存: &e{0}", + "price-per": "&a價格: &e一個 {0} {1} 元", + "total-value-of-chest": "&a箱子中物品總價: &e{0} 元", + "damage-percent-remaining": "&a耐久度: &e剩餘 {0}%", + "this-shop-is-buying": "&a此商店是 &d收購物品&a 的商店。", + "this-shop-is-selling": "&a此商店是 &b賣出物品&a 的商店。", + "effects": "&a藥水效果: &e{0}", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&c打開了一個上鎖的商店!", + "that-is-locked": "&c此商店已經上鎖!", + "how-many-buy": "&a在聊天室中輸入您想要 &b購買 &a的數量, 您可以購買 &e{0} &a個。輸入 &ball &a購買全部。", + "how-many-sell": "&a在聊天室中輸入您想要 &d出售 &a的數量, 您有 &e{0} &a個可以出售。輸入 &ball &a賣出全部。", + "not-allowed-to-create": "&c您無法在此創建商店。", + "blacklisted-item": "&c這件物品已被伺服器禁止販售!", + "how-much-to-trade-for": "&a請在聊天室中輸入每個 &e{0} &a的定價:", + "command": { + "toggle-unlimited": { + "unlimited": "&a這個商店現在已經沒有數量限制。", + "limited": "&a這個商店現在已經恢復數量限制。" + }, + "no-owner-given": "&c商店沒有指定擁有者, 使用 &a\/qs setowner <玩家名稱> &c來設定。", + "new-owner": "&a新商店主人: &e{0}", + "now-buying": "&a商店現在 &d收購 &e{0}", + "now-selling": "&a商店現在 &b販賣 &e{0}", + "cleaning": "&a正在清除已經被掃購一空 ( 庫存為 0 ) 的商店...", + "reloading": "&a重新載入中...", + "cleaned": "&a已經移除 &e{0} &a個商店", + "no-type-given": "&c用法: \/qs find <物品>", + "no-amount-given": "&c沒有提供數量, 請使用: &a\/qs refill <數量>", + "now-debuging": "&a成功切換到開發 (除錯) 模式, 重新載入 QuickShop 中...", + "now-nolonger-debuging": "&a成功切換到產品 (非除錯) 模式,重新載入 QuickShop 中...", + "wrong-args": "&c參數錯誤, 使用 \/qs help 查看指令列表", + "description": { + "title": "&aQuickShop 指令列表", + "unlimited": "&e讓商店沒有收售數量上限", + "setowner": "&e改變店主", + "owner": "&e改變店主", + "buy": "&e將商店更改為 &d收購&e 模式", + "sell": "&e將商店更改為 &b販賣&e 模式", + "price": "&e更改您商店的買賣價格", + "clean": "&e刪除所有 (已載入) 沒有商品的商店", + "find": "&e找到距離您最近的買賣特定商品的商店", + "reload": "&e重新載入 QuickShop 的 config.yml 文件", + "refill": "&e將一定數量的商品加到商店", + "empty": "&e從商店清空所有商品", + "debug": "&e切換到開發模式", + "create": "&e在目標儲物箱創建一個新商店", + "fetchmessage": "&e獲取未讀取的商店訊息", + "info": "&e顯示 QuickShop 的統計資料", + "paste": "&e自動將伺服器資料傳送到 Pastebin 上", + "staff": "&e管理您的商店店員", + "remove": "&e移除您所看著的商店", + "amount": "&e將您的動作執行指定的次數 (適用於聊天插件的問題)", + "about": "&e顯示關於 QuickShop 的訊息", + "help": "&e顯示 QuickShop 的指令", + "supercreate": "&e創建一個略過所有保護檢查的商店" + } + }, + "signs": { + "selling": "販賣 {0} 個", + "header": "&c{0}", + "buying": "收購 {0} 個", + "item": "{0}", + "price": "每個 {0}", + "unlimited": "無上限" + }, + "controlpanel": { + "setowner": "&a店主: &b{0} &e[&d&l變更&e]", + "infomation": "&a商店控制面板:", + "setowner-hover": "&e點擊變更店主。", + "unlimited": "&a無限制: {0} &e[&d&l切換&e]", + "unlimited-hover": "&e點擊切換商店買賣無上限模式。", + "mode-selling": "&a商店模式: &b販賣 &e[&d&l切換&e]", + "mode-selling-hover": "&e點擊將商店變成收購模式。", + "mode-buying": "&a商店模式: &b收購 &e[&d&l切換&e]", + "mode-buying-hover": "&e點擊將商店變成販賣模式。", + "price": "&a價錢: &b{0} &e[&d&l設定&e]", + "price-hover": "&e點擊變更商品價錢。", + "refill": "&a補貨: 重新填充商品 &e[&d&lOK&e]", + "refill-hover": "&e點擊重新填充商品。", + "empty": "&a清空: 刪除此商店內的所有商品 &e[&d&lOK&e]", + "empty-hover": "&e點擊清除商店內庫存。", + "remove": "&c&l[刪除商店]", + "remove-hover": "&e點擊刪除商店。", + "commands": { + "setowner": "\/qs setowner [玩家名稱]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [新價錢]", + "refill": "\/qs refill [數量]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a✔", + "failed": "&c✘" + }, + "tabcomplete": { + "price": "[價錢]", + "range": "[範圍]", + "amount": "[數量]" + }, + "updatenotify": { + "buttontitle": "[現在更新]", + "onekeybuttontitle": "[一鍵更新]", + "list": [ + "新版本 {0} 已經發布了, 您還在使用 {1}!", + "蹦! 新的版本 {0} 出來了, 快更新!", + "驚喜! 新版本 {0} 出來了, 您的版本是 {1}", + "看來您需要更新, {0} 已經發布了!", + "哎呀! 新版本 {0} 已經發布了, 您的版本是 {1}!", + "QuickShop 已經更新到 {0} 了, 您為什麼不更新?", + "修復並重新... 抱歉 {0} 已經發布了!", + "痾! 不, 這不是錯誤, 只是 {0} 版本剛發布了!", + "我的天啊! {0} 已經出來了! 您怎麼還在使用 {1}?", + "今日新聞: QuickShop 已經釋出 {0} 的更新!", + "插件已死, 您應該要更新到 {0}!", + "Fuze 正在咚更新 {0}, 保存更新!", + "新的更新指揮官 {0} 剛剛上任了!", + "看我的風格--- {0} 版本出來了, 您還在使用 {1} 版本", + "啊啊啊! 是新的版本 {0}! 快更新!", + "您在想什麼? {0} 已經釋出了! 快更新!" + ], + "remote-disable-warning": "&c這個版本的 QuickShop 已經被標記為禁用, 代表這個版本有十分嚴重的問題。從我們的 SpigotMC 頁面獲取更多資訊: {0} 。這則警告將持續顯示到您使用沒有被禁用的版本替代這個, 但不影響您的伺服器運行。", + "label": { + "unstable": "[不穩定 Unstable]", + "stable": "[穩定 Stable]", + "lts": "[長期支援 LTS]", + "qualityverifyed": "[品質認證 Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&c由於您的餘額不足, 您在 {0} 的商店已經被移除。", + "digits-reach-the-limit": "你的東西太貴了", + "complete": "&a完成!", + "quickshop-gui-preview": "商店物品預覽", + "shops-recovering": "正在嘗試從備份檔案中還原所有商店...", + "shops-backingup": "正在把商店資料備份到資料庫...", + "saved-to-path": "備份檔案已被儲存在{0}", + "backup-failed": "無法備份商店資料 試著查看控制台來檢視錯誤", + "translate-not-completed-yet-click": "語言 {0} 的翻譯已經完成{1} ! 想要幫助我們翻譯其他語言? 點擊這裡", + "translate-not-completed-yet-url": "語言 {0} 的翻譯已經完成{1} ! 想要幫助我們翻譯其他語言? 點擊這裡{2}", + "language-info-panel": { + "name": "語言: ", + "code": "代碼: ", + "progress": "進度: ", + "help": "幫助我們: ", + "translate-on-crowdin": "[在Crowdin上翻譯]" + } +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/de.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/de.json new file mode 100644 index 0000000..8e38618 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/de.json @@ -0,0 +1,234 @@ +{ + "translation-author": "\u00dcbersetzer: Jason897", + "translation-version": "Unterst\u00fctze Version: Reremake", + "translation-contributors": "Unterst\u00fctzer: Andre_601", + "translation-country": "Sprache: Deutsch (de_DE)", + "language-version": "27", + "not-looking-at-shop": "&cEs wurde kein Shop gefunden. Bitte schau auf einen Shop, um diese Aktion auszuf\u00fchren.", + "no-anythings-in-your-hand": "&cEs befindet sich kein Gegenstand in deiner Hand.", + "no-permission": "&cDu hast keine Berechtigung, dies zu tun.", + "no-creative-break": "&cDu kannst Shops von anderen Spielern nicht im Kreativmodus abbauen. Bitte wechsel in den \u00dcberlebensmodus.", + "no-double-chests": "&cDu kannst den Doppelkisten-Shop nicht erstellen.", + "shop-already-owned": "&cDas ist bereits ein Shop.", + "chest-was-removed": "&cDie Kiste wurde entfernt.", + "price-too-cheap": "&cDer Preis muss h\u00f6her als &e${0} sein", + "no-price-change": "&cDer Preis w\u00fcrde sich nicht \u00e4ndern!", + "you-cant-afford-a-new-shop": "&cDu ben\u00f6tigst {0}, um einen neuen Shop zu erstellen.", + "player-bought-from-your-store-tax": "&c{0} hat {1} {2} in deinem Shop eingekauft. Dabei wurden {3} Steuern f\u00e4llig.", + "you-cant-afford-to-change-price": "&cEs kostet {0}, um den Preis zu ver\u00e4ndern.", + "success-created-shop": "&aShop wurde erstellt.", + "success-removed-shop": "&aShop wurde entfernt.", + "shops-arent-locked": "&cNicht vergessen, dass Shops NICHT gegen Diebstahl gesichert sind! Wenn du Diebe aufhalten willst, musst du sie mit LWC, Lockette, etc. sch\u00fctzen!", + "shop-creation-cancelled": "&cErstellung abgebrochen.", + "shop-purchase-cancelled": "&cKauf abgebrochen.", + "shop-stock-too-low": "&cDer Shop verf\u00fcgt nur noch \u00fcber {0} {1}", + "you-cant-afford-to-buy": "&cDies w\u00fcrde {0} kosten, du hast aber lediglich {1}", + "negative-amount": "&cEingabe ung\u00fcltig. Eine negative Anzahl ist nicht m\u00f6glich", + "not-a-number": "&cEs d\u00fcrfen nur Zahlen eingegeben werden, aber du hast {0} eingegeben", + "not-a-integer": "&cEs d\u00fcrfen nur ganze Zahlen eingegeben werden, aber du hast {0} eingegeben", + "player-bought-from-your-store": "&c{0} hat {1} {2} in deinem Shop eingekauft.", + "shop-out-of-stock": "&5Dein Shop bei den Koordinaten {0}, {1}, {2}, verf\u00fcgt \u00fcber keine {3} mehr", + "shop-has-no-space": "&cDer Shop hat nur noch Platz f\u00fcr {0} weitere {1}.", + "you-dont-have-that-many-items": "&cDu hast nur {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cDies w\u00fcrde {0} kosten, aber der Besitzer hat nur {1}", + "player-sold-to-your-store": "&a{0} hat {1} {2} bei deinem Shop verkauft.", + "shop-out-of-space": "&5Dein Shop bei den Koordinaten {0}, {1}, {2}, ist jetzt voll.", + "fee-charged-for-price-change": "&aDu hast &c{0}&a bezahlt, um den Preis zu \u00e4ndern.", + "price-is-now": "&aDer neue Preis ist nun &e{0}", + "thats-not-a-number": "&cUng\u00fcltige Zahl", + "no-price-given": "&cBitte gebe einen g\u00fcltigen Preis ein.", + "average-price-nearby": "&aDer durchschnittliche Preis in der Umgebung ist &e{0}", + "shop-has-changed": "&cDer Shop, den du gerade benutzt wolltest, wurde ver\u00e4ndert seit dem du drauf geklickt hast!", + "shop-not-exist": "&cDieser Shop existiert nicht.", + "nearby-shop-this-way": "&aDieser Shop ist {0} Bl\u00f6cke von dir entfernt.", + "no-nearby-shop": "&cIn der Umgebung befindet sich kein Shop mit {0}.", + "buying-more-than-selling": "&cWARNUNG: Du kaufst diesen Gegenstand f\u00fcr mehr Geld als du ihn verkaufst!", + "not-enough-space": "&cDu hast nur noch Platz f\u00fcr {0} mehr davon!", + "refill-success": "&aDer Shop wurde erfolgreich aufgef\u00fcllt.", + "empty-success": "&aDer Shop wurde erfolgreich geleert.", + "admin-shop": "AdminShop", + "unknown-owner": "Unbekannt", + "owner-bypass-check": "&eAlle \u00dcberpr\u00fcfungen wurden ignoriert, der Handel war erfolgreich! (Du bist der Besitzer des Shops)", + "reached-maximum-can-create": "&cDu hast bereits das Maximum von {0}\/{1} Shops erreicht!", + "restricted-prices": "&cDer Pres von {0} wurde eingeschr\u00e4nkt. Dieser muss mindestens {1} und darf maximal {2} betragen.", + "no-enough-money-to-keep-shops": "&cDu hattest nicht genug Geld, um deine Shops zu behalten! Daher wurden all deine Shops entfernt...", + "nothing-to-flush": "&aEs gibt keine neuen Nachrichten zu deinem Shop.", + "break-shop-use-supertool": "&eDu kannst diesen Shop mithilfe des SuperTools zerst\u00f6ren.", + "failed-to-put-sign": "&cEs gibt keinen Platz um den Shop, um das Informationsschild zu platzieren.", + "failed-to-paste": "&cDer Upload zu Pastebin war nicht m\u00f6glich. Bitte \u00fcberpr\u00fcfe deine Internetverbindung und versuche es erneut. (Siehe Konsole f\u00fcr Details)", + "warn-to-paste": "&eSammelt Daten und l\u00e4dt diese anschlie\u00dfend auf Pastebin hoch, dies kann eine Weile dauern. &c&lAchtung&c: Die hochgeladenen Daten werden dort eine Woche lang gespeichert. Die Daten k\u00f6nnen m\u00f6glicherweise Konfigurationseinstellungen oder andere sensitive Daten enthalten. Stelle sicher diese nur Teammitgliedern und Entwicklern zu Verf\u00fcgung zu stellen, denen du &lvertraust.", + "price-too-high": "&cDer Preis ist zu hoch! Du kannst keinen Shop erstellen mit einem Preis \u00fcber {0}.", + "you-cant-create-shop-in-there": "&cDu bist nicht berechtigt an diesem Ort ein Shop zu erstellen.", + "unknown-player": "&cDieser Spieler existiert nicht. Bitte \u00fcberpr\u00fcfe, ob der Name korrekt geschrieben wurde.", + "shop-staff-cleared": "&aEs wurden erfolgreich alle Mitarbeiter deines Shops entfernt.", + "shop-staff-added": "&a{0} erfolgreich als Shop-Mitarbeiter hinzugef\u00fcgt.", + "shop-staff-deleted": "&a{0} erfolgreich als Shop-Mitarbeiter entfernt.", + "no-permission-build": "&cDu kannst hier keinen Shop erstellen.", + "success-change-owner-to-server": "&aDer Shop wurde erfolgreich dem Server \u00fcberschrieben.", + "flush-finished": "&aDie Nachrichten wurden erfolgreich abgerufen.", + "purchase-failed": "&cKauf fehlgeschlagen: Interner Fehler, bitte kontaktiere einen Serveradministrator.", + "no-pending-action": "&cDu hast keine ausstehende Aktion", + "permission-denied-3rd-party": "&cZugriff verweigert: Drittanbieter-Plugin [{0}].", + "menu": { + "successful-purchase": "&aFolgendes wurde erfolgreich gekauft:", + "successfully-sold": "&aFolgendes wurde erfolgreich verkauft:", + "item-name-and-price": "&e{0} {1} &af\u00fcr &e{2}", + "sell-tax": "&aDu hast &e{0} &aan Steuern zahlen m\u00fcssen.", + "sell-tax-self": "&aDu bist der Besitzer des Shops, also fallen f\u00fcr dich keine Steuern an.", + "enchants": "&5Verzauberungen", + "stored-enchants": "&5Verf\u00fcgt \u00fcber Verzauberungen", + "shop-information": "&aShop Informationen:", + "owner": "&aBesitzer: {0}", + "item": "&aGegenstand: &e{0}", + "preview": "&b[Gegenstandsvorschau]", + "space": "&aKapazit\u00e4t: &e{0}", + "stock": "&aLagerbestand: &e{0}", + "price-per": "&aPreis pro &e{0} &a- &e{1}", + "total-value-of-chest": "&aGesamtwert des Kiste: &e{0}", + "damage-percent-remaining": "&e{0}% &a\u00dcbrig (Haltbarkeit).", + "this-shop-is-buying": "&aDieser Shop &dKAUFT&a Gegenst\u00e4nde an.", + "this-shop-is-selling": "&aDieser Shop &bVERKAUFT&a Gegenst\u00e4nde.", + "effects": "&aEffekte", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cUmgehe einen QuickShop schutz!", + "that-is-locked": "&cDieser Shop ist gesch\u00fctzt.", + "how-many-buy": "&aSchreibe in den Chat, wieviele du &bKAUFEN&a m\u00f6chtest. Du kannst &e{0}&a St\u00fcck kaufen. Gib &ball&a ein um alle zu kaufen.", + "how-many-sell": "&aSchreibe in den Chat, wieviele du &dVERKAUFEN&a m\u00f6chtest. Du hast noch &e{0}&a verf\u00fcgbar. Gib &ball&a ein um alle zu verkaufen.", + "not-allowed-to-create": "&cDu kannst hier keinen Shop erstellen.", + "blacklisted-item": "&cDieser Gegenstand wurde vom Verkauf ausgeschlossen.", + "how-much-to-trade-for": "&aSchreibe jetzt den Preis f\u00fcr einen &e{0}&a in den Chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aDer Shop ist nun unlimitiert", + "limited": "&aDer Shop ist nun limitiert" + }, + "no-owner-given": "&cDieser Shop verf\u00fcgt \u00fcber keinen Besitzer. Benutze &a\/qs setowner &c um einen Besitzer festzulegen.", + "new-owner": "&aNeuer Besitzer: &e{0}", + "now-buying": "&e{0} &awerden jetzt &dANGEKAUFT", + "now-selling": "&e{0} &awerden jetzt &dVERKAUFT", + "cleaning": "&aShops ohne Lagerbestand werden jetzt entfernt...", + "reloading": "&aWird neu geladen...", + "cleaned": "&e{0}&a Shops wurden entfernt.", + "no-type-given": "&cVerwendung: \/qs find ", + "no-amount-given": "&cKeine Anzahl angegeben. Benutze &a\/qs refill &c", + "now-debuging": "&aDer Entwicklermodus wurde erfolgreich aktiviert. QuickShop l\u00e4dt jetzt neu...", + "now-nolonger-debuging": "&aDer Entwicklermodus wurde erfolgreich deaktiviert. QuickShop l\u00e4dt jetzt neu...", + "wrong-args": "&cParameter stimmen nicht \u00fcberein. Siehe \/qs help f\u00fcr Hilfe", + "description": { + "title": "&aQuickShop Hilfe", + "unlimited": "&eMacht einen Shop unlimitiert", + "setowner": "&e\u00c4ndert den Besitzer des Shops", + "owner": "&e\u00c4ndert den Besitzer des Shops", + "buy": "&e\u00c4ndert einen Shop zu &dKAUF&e-Modus", + "sell": "&e\u00c4ndert einen Shop zu &bVERKAUF&e-Modus", + "price": "&eVer\u00e4ndert den Kauf-\/Verkaufspreis f\u00fcr den jeweiligen Shop", + "clean": "&eEntferne alle (geladenen) Shops ohne Lagerbestand", + "find": "&eErmittelt den n\u00e4chsten Shop in der Umgebung mit dem gesuchten Gegenstand.", + "reload": "&eL\u00e4dt die config.yml von QuickShop neu", + "refill": "&eF\u00fcgt eine gegebene Anzahl an Gegenst\u00e4nden dem Shop hinzu.", + "empty": "&eEntferne den Lagerbestand von einem Shop", + "debug": "&eWechselt in den Entwicklermodus", + "create": "&eErstelle einen neuen Shop bei der angeschauten Kiste", + "fetchmessage": "&eZeigt alle ungelesene Nachrichten zum Shop an", + "info": "&eZeigt Statistiken zu QuickShop an", + "paste": "&eAutomatischer Upload der Daten zu Pastebin", + "staff": "&eVerwalte die Mitarbeiter deines Shops", + "remove": "&eEntfernt den Shop den du anschaust", + "amount": "&eZum eingeben einer Zahl, falls die Eingabe \u00fcber den Chat nicht funktioniert", + "about": "&eZeigt die Informationen \u00fcber den QuickShop", + "help": "&eZeigt die QuickShop-Hilfe", + "supercreate": "&eErstellt einen Shop der alle Schutz\u00fcberpr\u00fcfungen umgeht" + } + }, + "signs": { + "selling": "Verkauft {0}", + "header": "&c{0}", + "buying": "Kauft {0}", + "item": "{0}", + "price": "{0} p. St.", + "unlimited": "Unlimitiert " + }, + "controlpanel": { + "setowner": "&aBesitzer: &b{0} &e[&d&l\u00c4ndern&e]", + "infomation": "&aShop Bedienpanel:", + "setowner-hover": "&eKlicke hier um den Besitzer zu wechseln.", + "unlimited": "&aUnlimitiert: {0} &e[&d&l\u00c4ndern&e]", + "unlimited-hover": "&eKlicke hier um umzuschalten, ob der Shop unlimitiert ist.", + "mode-selling": "&aShop-Modus: &bVerkaufen &e[&d&l\u00c4ndern&e]", + "mode-selling-hover": "&eKlicke hier um den Shop in den Ankaufmodus umzuschalten.", + "mode-buying": "&aShop-Modus: &bAnkaufen &e[&d&l\u00c4ndern&e]", + "mode-buying-hover": "&eKlicke hier um den Shop in den Verkaufmodus umzuschalten.", + "price": "&aPreis: &b{0} &e[&d&l\u00c4ndern&e]", + "price-hover": "&eKlicke hier um einen neuen Preis f\u00fcr den Shop festzulegen.", + "refill": "&aAuff\u00fcllen: F\u00fclle die Gegenst\u00e4nde im Shop auf &e[&d&lOK&e]", + "refill-hover": "&eKlicke hier um den Shop aufzuf\u00fcllen.", + "empty": "&aLeeren: Entfernt alle Gegenst\u00e4nde aus dem Shop &e[&d&lOK&e]", + "empty-hover": "&eKlicke hier um den Shop zu leeren.", + "remove": "&c&l[Shop entfernen]", + "remove-hover": "&eKlicke um diesen Shop zu entfernen.", + "commands": { + "setowner": "\/qs setowner [Spieler]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [Neuer Preis]", + "refill": "\/qs refill [Anzahl]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a\u2714", + "failed": "&c\u2718" + }, + "tabcomplete": { + "price": "[Preis]", + "range": "[Reichweite]", + "amount": "[Anzahl]" + }, + "updatenotify": { + "buttontitle": "[Jetzt Aktualisieren]", + "onekeybuttontitle": "[Ein Klick Update]", + "list": [ + "{0} ist bereits ver\u00f6ffentlicht, du verwendest noch immer {1}!", + "Boom! Neuse update {0} kommt, Aktualisiere!", + "\u00dcberraschung! {0} ist erschienen, der Server ist aber noch auf {1}", + "Sieht so aus, als solltest du mal das Plugin aktualisieren, {0} ist verf\u00fcgbar!", + "Ooops! {0} ist verf\u00fcgbar, es wird aber noch {1} verwendet!", + "Ich schw\u00f6r, QS wurde geupdated {0}, warum hast du noch nicht die neue Version?", + "Fehlerbehebu.. Sorry {0} ist verf\u00fcgbar!", + "Err! Nein, dies ist kein Fehler, {0} ist verf\u00fcgbar!", + "OMG! {0} ist erschienen! Warum verwendest du immer noch {1}?", + "Heutige Neuigkeit: Es gibt eine neue Version von QuickShop {0}!", + "Plugin K.I.A, du solltest zu {0} updaten!", + "Brand Neues Update {0}!", + "Kommandeur es gibt ein Update! {0} ist grade erschienen!", + "Schau mich an---{0} update, du bist noch auf {1}", + "Ahhhhhhh! Neues Update {0}! Update!", + "Was denkst du? {0} ist drau\u00dfen! Update!" + ], + "remote-disable-warning": "&cDiese Version von QuickShop wird vom Remote-Server als deaktiviert markiert, das bedeutet, dass diese Version ein ernsthaftes Problem haben k\u00f6nnte. Details findest du auf unserer SpigotMC-Seite: {0}. Diese Warnung wird angezeigt und spammt deine Konsole zu, bis du eine andere, nicht deaktivierte Version verwendest, um diese zu ersetzen. Dies hat keine Auswirkungen auf den Server.", + "label": { + "unstable": "[Instabil]", + "stable": "[Stabil]", + "lts": "[LTS]", + "qualityverifyed": "[Qualit\u00e4t]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cDein Shop bei den Koordinaten {0} wurde entfernt, da du nicht genug Geld hattest um ihn zu behalten!", + "digits-reach-the-limit": "&cDu hast das Limit an Nachkommastellen f\u00fcr den Preis erreicht.", + "complete": "&aAbgeschlossen!" +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/en-US.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/en-US.json new file mode 100644 index 0000000..560d6ed --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/en-US.json @@ -0,0 +1,234 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "27", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "no-creative-break": "&cYou cannot break other players shops in creative mode. Use survival instead.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a\u2714", + "failed": "&c\u2718" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!" +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/en.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/en.json new file mode 100644 index 0000000..560d6ed --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/en.json @@ -0,0 +1,234 @@ +{ + "translation-author": "Translator: Ghost_chu", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Contributors: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Language Zone: English (en_US)", + "language-version": "27", + "not-looking-at-shop": "&cNo QuickShop was found, you must be looking at one.", + "no-anythings-in-your-hand": "&cThere is nothing in your hand.", + "no-permission": "&cYou do not have permission to do that.", + "no-creative-break": "&cYou cannot break other players shops in creative mode. Use survival instead.", + "no-double-chests": "&cYou cannot create the DoubleChest shop.", + "shop-already-owned": "&cThat is already a shop.", + "chest-was-removed": "&cThe chest was removed.", + "price-too-cheap": "&cPrice must be greater than &e${0}", + "no-price-change": "&cThat wouldn't result in a price change!", + "you-cant-afford-a-new-shop": "&cIt costs {0} to create a new shop.", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cIt costs {0} to change the price in your shop.", + "success-created-shop": "&aCreated shop.", + "success-removed-shop": "&aShop removed.", + "shops-arent-locked": "&cRemember, shops are NOT protected from theft! If you want to stop thieves, lock it with LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCancelled Shop Creation.", + "shop-purchase-cancelled": "&cCancelled Shop Purchase.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cThat costs {0}, but you only have {1}", + "negative-amount": "&cDerp, can't trade negative amounts", + "not-a-number": "&cThere can only be number, but you input {0}", + "not-a-integer": "&cThere can only be integer, but you input {0}", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cInvalid number", + "no-price-given": "&cPlease give a valid price.", + "average-price-nearby": "&aAverage Price Nearby: &e{0}", + "shop-has-changed": "&cThe shop you tried to use has changed since you clicked it!", + "shop-not-exist": "&cThere had no shop.", + "nearby-shop-this-way": "&aShop is {0} blocks away from you.", + "no-nearby-shop": "&cNo shops matching {0} nearby.", + "buying-more-than-selling": "&cWARNING: You are buying items for more than you are selling them!", + "not-enough-space": "&cYou only have room for {0} more of that!", + "refill-success": "&aRefill success", + "empty-success": "&aEmpty success", + "admin-shop": "AdminShop", + "unknown-owner": "Unknown", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a\u2714", + "failed": "&c\u2718" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!" +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/es-419.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/es-419.json new file mode 100644 index 0000000..006fc33 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/es-419.json @@ -0,0 +1,234 @@ +{ + "translation-author": "&c&lTraductores: &b&lGhost_chu, LoudCloud,DorianXYZ, ERDUKE21 y Ant4rez", + "translation-version": "&c&lVersi\u00f3n soportada: &b&lReremake", + "translation-contributors": "&c&lContribuyentes: &b&lTimtower, Netherfoam, KaiNoMood, Mgazul, LoudCloud, CKittycannon, ERDUKE21 y Ant4rez", + "translation-country": "&c&lZona de lenguaje: &b&lEspa\u00f1ol (es_LA)", + "language-version": "27", + "not-looking-at-shop": "&cNo se encontr\u00f3 ninguna QuickShop, debes estar mirando una.", + "no-anythings-in-your-hand": "&cNo hay nada en tu mano.", + "no-permission": "&cNo tienes permiso para hacer eso.", + "no-creative-break": "&cNo puedes destruir las tiendas de otros jugadores en modo Creativo. Debes usar el modo Supervivencia.", + "no-double-chests": "&cNo puedes crear tiendas de cofres dobles.", + "shop-already-owned": "&cEso ya es una tienda.", + "chest-was-removed": "&cEl cofre ha sido removido.", + "price-too-cheap": "&cEl precio debe ser mayor a &e${0}", + "no-price-change": "&c\u00a1Eso no va a alterar el precio!", + "you-cant-afford-a-new-shop": "&cCuesta {0} crear una tienda.", + "player-bought-from-your-store-tax": "&c{0} ha comprado {1} {2} en tu tienda, y has pagado {3} en impuestos.", + "you-cant-afford-to-change-price": "&cCuesta {0} para cambiar el precio en tu tienda.", + "success-created-shop": "&aTienda creada.", + "success-removed-shop": "&aLa tienda ha sido eliminada.", + "shops-arent-locked": "&c\u00a1Recuerda, las tiendas NO EST\u00c1N PROTEGIDAS contra el robo! Si quieres detener a los ladrones, protege tu cofre con LWC, Lockette, BlockLocker, etc.", + "shop-creation-cancelled": "&cSe cancel\u00f3 la creaci\u00f3n de la tienda.", + "shop-purchase-cancelled": "&cSe cancel\u00f3 la compra de la tienda.", + "shop-stock-too-low": "&cS\u00f3lo queda {0} {1} en la tienda", + "you-cant-afford-to-buy": "&cEso cuesta {0}, pero s\u00f3lo tienes {1}", + "negative-amount": "&cRayos, no se puede intercambiar cantidades negativas", + "not-a-number": "&cSolo puede haber n\u00fameros, pero tu ingresaste {0}", + "not-a-integer": "&cSolo puede haber un numero entero, pero tu ingresaste {0}", + "player-bought-from-your-store": "&c{0} compr\u00f3 {1} {2} de tu tienda.", + "shop-out-of-stock": "&5Tu tienda en {0}, {1}, {2}, se ha quedado sin {3}", + "shop-has-no-space": "&cLa tienda s\u00f3lo tiene espacio para {0} m\u00e1s {1}.", + "you-dont-have-that-many-items": "&cSolo tienes {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cEso cuesta {0} pero el due\u00f1o solo tiene {1}", + "player-sold-to-your-store": "&a{0} vendido {1} {2} a su tienda.", + "shop-out-of-space": "&5Su tienda en {0}, {1}, {2}, ahora est\u00e1 llena.", + "fee-charged-for-price-change": "&aPagas &c{0}&a para cambiar el precio.", + "price-is-now": "&aEl nuevo precio de las tiendas es &e{0}.", + "thats-not-a-number": "&cN\u00famero inv\u00e1lido.", + "no-price-given": "&cPor favor ingresa un precio v\u00e1lido.", + "average-price-nearby": "&aPrecio promedio local: &e{0}", + "shop-has-changed": "&c\u00a1La tienda que trataste de usar ha cambiado desde que la clickeaste!", + "shop-not-exist": "&cNo hab\u00eda una tienda.", + "nearby-shop-this-way": "&aLa tienda est\u00e1 a {0} bloques de ti.", + "no-nearby-shop": "&cNo hay tiendas de {0} cerca.", + "buying-more-than-selling": "&cATENCI\u00d3N: \u00a1Est\u00e1s comprando art\u00edculos por m\u00e1s de lo que los est\u00e1s vendiendo!", + "not-enough-space": "&c\u00a1S\u00f3lo tienes espacio para {0} m\u00e1s!", + "refill-success": "&aCorrectamente rellenado", + "empty-success": "&aCorrectamente vaciado", + "admin-shop": "Tienda Admin", + "unknown-owner": "Desconocido", + "owner-bypass-check": "&eOmitidas todas las pruebas, \u00a1intercambio correcto! (T\u00fa eres el due\u00f1o de la tienda)", + "reached-maximum-can-create": "&c\u00a1Ya tienes creadas un m\u00e1ximo de {0}\/{1} tiendas!", + "restricted-prices": "&cPrecios restringidos para {0}: min {1}, max {2}", + "no-enough-money-to-keep-shops": "&c\u00a1No tienes suficiente dinero para mantener tus tiendas! Todas las tiendas han sido eliminadas...", + "nothing-to-flush": "&aNo tienes mensajes de tus tiendas.", + "break-shop-use-supertool": "&ePuedes romper la tienda usando la SuperTool.", + "failed-to-put-sign": "&cNo hay suficiente espacio alrededor de la tienda para poner el letrero informativo.", + "failed-to-paste": "&cNo se pudo subir la informaci\u00f3n a PasteBin. Comprueba tu conexi\u00f3n a internet e intenta de nuevo. (Revisa la consola para m\u00e1s detalles)", + "warn-to-paste": "&eReuniendo datos y subi\u00e9ndolos a Pastebin, esto puede tardar un poco. &c&lAtenci\u00f3n&c, Los datos ser\u00e1n p\u00fablicos por una semana, pueden revelar la configuraci\u00f3n de tu servidor as\u00ed como otros datos privados, aseg\u00farate de mandarla s\u00f3lo al &lPersonal o desarrolladores&c de confianza.", + "price-too-high": "&c\u00a1El precio de la tienda es demasiado alto! No puedes crear una si cuesta m\u00e1s de {0}", + "you-cant-create-shop-in-there": "&cNo tienes permiso para crear una tienda en este lugar.", + "unknown-player": "&cDicho jugador no existe, por favor revisa el nombre de usuario que escribiste.", + "shop-staff-cleared": "&aRetirado todo el personal de tu tienda correctamente.", + "shop-staff-added": "&aAgregado\/s {0} correctamente a tu personal.", + "shop-staff-deleted": "&aSe eliminaron exitosamente {0} del personal de su tienda.", + "no-permission-build": "&cNo puedes montar una tienda aqu\u00ed.", + "success-change-owner-to-server": "&aEstablecido exitosamente el due\u00f1o de la tienda al Servidor.", + "flush-finished": "&aPurg\u00f3 con \u00e9xito los mensajes.\n", + "purchase-failed": "&cFall\u00f3 la compra: Error Interno, por favor contacte al administrador del servidor.", + "no-pending-action": "&cNo tienes ninguna acci\u00f3n pendiente", + "permission-denied-3rd-party": "&cPermiso denegado: complementos de terceros [{0}].", + "menu": { + "successful-purchase": "&aCompra exitosa:", + "successfully-sold": "&aVenta exitosa:", + "item-name-and-price": "&e{0} {1} &apor &e{2}", + "sell-tax": "&aPagaste &e{0} &aen impuestos.", + "sell-tax-self": "&aEsta tienda te pertenece, por lo que no pagas impuestos.", + "enchants": "&5Encantamientos", + "stored-enchants": "&5Encantamientos almacenados", + "shop-information": "&aDescripci\u00f3n de tienda:", + "owner": "&aPropietario: {0}", + "item": "&aArticulo: &e{0}", + "preview": "&b[Previsualizar]", + "space": "&aEspacio: &e{0}", + "stock": "&aAlmacenado &e{0}", + "price-per": "&aPrecio por &e{0} &a- &e{1}", + "total-value-of-chest": "&aValor total del cofre: &e{0}", + "damage-percent-remaining": "&e{0}% &aRestante.", + "this-shop-is-buying": "&aEsta tienda est\u00e1 &dCOMPRANDO&a art\u00edculos.", + "this-shop-is-selling": "&aEsta tienda est\u00e1 &dVENDIENDO&a art\u00edculos.", + "effects": "&aEfectos", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&c\u00a1Omitiendo el bloqueo de una QuickShop!", + "that-is-locked": "&cLa tienda est\u00e1 bloqueada.", + "how-many-buy": "&aIngresa cuanto deseas &bCOMPRAR&a en el chat. Ingresa &ball&a para comprarlo todo.", + "how-many-sell": "&aIngresa cuanto deseas &bVENDER&a en el chat. Tienes &e{0}&a disponible. Ingresa &ball& para venderlo todo.", + "not-allowed-to-create": "&cNo puedes crear una tienda aqu\u00ed.", + "blacklisted-item": "&cArt\u00edculo en lista negra. No puedes venderlo", + "how-much-to-trade-for": "&aIntroduce cu\u00e1nto pides por un &e{0}&a en el chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aLa tienda ahora es ilimitada.", + "limited": "&aLa tienda ahora es limitada." + }, + "no-owner-given": "&cNo se especific\u00f3 propietario. Usa &a\/qs setowner &c", + "new-owner": "&aNuevo due\u00f1o: &e{0}", + "now-buying": "&aAhora &dCOMPRANDO &e{0}", + "now-selling": "&aAhora &dVENDIENDO &e{0}", + "cleaning": "&aLimpiando tiendas sin existencias...", + "reloading": "&aRecargando...", + "cleaned": "&e{0}&a Tiendas han sido limpiadas", + "no-type-given": "&cUso: \/qs find ", + "no-amount-given": "&cNo se especific\u00f3 cantidad. Usa &a\/qs refill &c", + "now-debuging": "&aCambio con \u00e9xito a modo desarrollador, Recargando QuickShop...", + "now-nolonger-debuging": "&aCambio con \u00e9xito a modo producci\u00f3n, Recargando QuickShop...", + "wrong-args": "&cLos par\u00e1metros no coinciden, usa \/qs help para revisar la ayuda", + "description": { + "title": "&aQuickShop Ayuda", + "unlimited": "&eCrea una tienda ilimitada", + "setowner": "&eCambia qui\u00e9n es el propietario de una tienda", + "owner": "&eCambia qui\u00e9n es el propietario de una tienda", + "buy": "&eConvierte una tienda a modo &dCOMPRA", + "sell": "&eConvierte una tienda a modo &dVENTA", + "price": "&eCambia el precio de compra o venta de una de tus tiendas", + "clean": "&eElimina todas las tiendas (cargadas) fuera de existencias", + "find": "&eLocaliza la tienda m\u00e1s cercana de un tipo espec\u00edfico", + "reload": "&eRecarga el archivo config.yml de QuickShop", + "refill": "&eAgrega un n\u00famero dado de art\u00edculos a la tienda", + "empty": "&eElimina todo el stock de la tienda", + "debug": "&eCambia a modo desarrollador", + "create": "&eCrea una nueva tienda en el cofre objetivo", + "fetchmessage": "&eBusca mensajes de tienda no le\u00eddos", + "info": "&eMuestra estad\u00edsticas de QuickShop", + "paste": "&eCarga autom\u00e1ticamente datos del servidor a Pastebin", + "staff": "&eAdministra el personal de tu tienda", + "remove": "&eQuita la tienda que est\u00e1s mirando", + "amount": "&eEjecuta tus acciones con una cantidad (Por problemas del complemento de chat)", + "about": "&eMuestra informaci\u00f3n de QuickShop", + "help": "&eMuestra la ayuda de QuickShop", + "supercreate": "&eCrea una tienda que omita todas las pruebas de seguridad." + } + }, + "signs": { + "selling": "Vendiendo {0}", + "header": "&c{0}", + "buying": "Comprando {0}", + "item": "{0}", + "price": "{0} por unidad.", + "unlimited": "Ilimitado" + }, + "controlpanel": { + "setowner": "&aPropietario: &b{0} &e[&d&lCambiar&e]", + "infomation": "&aPanel de Control de la Tienda:", + "setowner-hover": "&eClick para cambiar el due\u00f1o.", + "unlimited": "&aIlimitado: {0} &e[&d&lAlternar&e]", + "unlimited-hover": "&eClick para alternar si la tienda tiene o no l\u00edmite.", + "mode-selling": "&aModo: &bVenta &e[&d&lAlternar&e]", + "mode-selling-hover": "&eClick para alternar la tienda al modo compra.", + "mode-buying": "&aModo: &bCompra &e[&d&lAlternar&e]", + "mode-buying-hover": "&eClick para alternar la tienda al modo de venta.", + "price": "&aPrecio: &b{0} &e[&d&lEstablecer&e]", + "price-hover": "&eClick para establecer un nuevo precio para esta tienda.", + "refill": "&aRellenar: Reaprovisiona los art\u00edculos de la tienda &e[&d&lOK&e]", + "refill-hover": "&eClick para reaprovisionar la tienda.", + "empty": "&aVaciar: Elimina todos los art\u00edculos de la tienda &e[&d&lOK&e]", + "empty-hover": "&eClick para limpiar el inventario de la tienda.", + "remove": "&c&l[Eliminar tienda]", + "remove-hover": "&eClick para eliminar esta tienda.", + "commands": { + "setowner": "\/qs setowner [Jugador]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [Nuevo Precio]", + "refill": "\/qs refill [Cantidad]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "|" + }, + "booleanformat": { + "success": "&a\u2714", + "failed": "&c\u2718" + }, + "tabcomplete": { + "price": "[precio]", + "range": "[rango]", + "amount": "[cantidad]" + }, + "updatenotify": { + "buttontitle": "[Actualizar Ahora]", + "onekeybuttontitle": "[Actualizaci\u00f3n Autom\u00e1tica]", + "list": [ + "\u00a1{0} ha sido lanzada, t\u00fa sigues utilizando {1}!", + "\u00a1Boom! Llega la nueva actualizaci\u00f3n {0}. \u00a1Actualiza!", + "\u00a1Sorpresa! {0} ha salido, t\u00fa est\u00e1s en {1}", + "Parece que necesitas actualizar, \u00a1{0} ha sido lanzada!", + "\u00a1Ooops! {0} ha sido lanzada ya, \u00a1t\u00fa est\u00e1s en {1}!", + "Lo prometo, QS se ha actualizado a {0}, \u00bfpor qu\u00e9 no has actualizado?", + "Arreglando y re... Lo siento, \u00a1{0} ha sido lanzada!", + "\u00a1Err! Nope, no es un error, \u00a1{0} acaba de salir!", + "\u00a1OMG! {0} ya sali\u00f3! \u00bfPor qu\u00e9 a\u00fan usas {1}?", + "Noticias del d\u00eda: \u00a1QuickShop ha sido actualizado a {0}!", + "Plugin muerto en combate, \u00a1deber\u00edas actualizar a {0}!", + "El actualizador puede actualizar a {0}, \u00a1guarda la actualizaci\u00f3n!", + "Hay una nueva versi\u00f3n, comandante, \u00a1{0} acaba de salir!", + "Mira, mira---{0} se ha actualizado, sigues usando {1}", + "\u00a1Ahhhhhhh! \u00a1Nueva versi\u00f3n {0}! \u00a1Actualiza!", + "\u00bfEn qu\u00e9 est\u00e1s pensando? {0} \u00a1ya fue lanzada! \u00a1Actualiza!" + ], + "remote-disable-warning": "\u00a7cEsta versi\u00f3n de QuickShop esta marcada como deshabilitado por servidor remoto, quiere decir que esta versi\u00f3n puede tener serios problemas, obt\u00e9n detalles de nuestra pagina de SpigotMC: {0}. Esta advertencia aparecer\u00e1 y llenara tu consola de mensajes hasta que uses otra versi\u00f3n no deshabilitada para reemplazar esta, no afectara el funcionamiento de su servidor.", + "label": { + "unstable": "[Inestable]", + "stable": "[Estable]", + "lts": "[LTS]", + "qualityverifyed": "[Calidad]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Maestro]" + } + }, + "shop-removed-cause-ongoing-fee": "&c\u00a1Su tienda en {0} fue removida debido a que no tienes suficiente dinero para mantenerla!", + "digits-reach-the-limit": "&cHas alcanzado el l\u00edmite de d\u00edgitos antes del punto decimal en el precio.", + "complete": "&a\u00a1Terminado!" +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/fi.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/fi.json new file mode 100644 index 0000000..1c7275d --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/fi.json @@ -0,0 +1,234 @@ +{ + "translation-author": "K\u00e4\u00e4nt\u00e4j\u00e4: &b&lSpeek (https:\/\/speek.fi\/)", + "translation-version": "Tuettu versio: Reremake", + "translation-contributors": "Ohjelmointi-apu: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Kielialue: Suomi (fi_FI)", + "language-version": "27", + "not-looking-at-shop": "&cKauppaa ei l\u00f6ytynyt. Sinun pit\u00e4\u00e4 katsoa muokattavaa kauppaa p\u00e4in.", + "no-anythings-in-your-hand": "&cK\u00e4dess\u00e4si ei ole mit\u00e4\u00e4n.", + "no-permission": "&cSinulla ei ole oikeutta tehd\u00e4 noin.", + "no-creative-break": "&cEt voi rikkoa muiden pelaajien kauppoja luovassa tilassa. K\u00e4yt\u00e4 ennemmin seikkailutilaa.", + "no-double-chests": "&cEt voi luoda tupla-arkkukauppaa", + "shop-already-owned": "&cTuo on jo kauppa!", + "chest-was-removed": "&cKauppa poistettiin onnisteuneesti.", + "price-too-cheap": "&cHinnan pit\u00e4\u00e4 olla korkeampi kuin &e${0}", + "no-price-change": "&cTuo ei vaihtaisi kaupan hintaa!", + "you-cant-afford-a-new-shop": "&cKaupan luominen maksaa {0}.", + "player-bought-from-your-store-tax": "&cPelaaja {0} osti {1} {2} kaupasta ja maksoit siit\u00e4 {3} veroja.", + "you-cant-afford-to-change-price": "&cHinnan vaihtaminen maksaa {0}.", + "success-created-shop": "&cKaupan luonti peruutettiin.", + "success-removed-shop": "&aKauppa poistettiin onnistuneesti", + "shops-arent-locked": "&cMuista, kaupat EI ole suojattu varkailta! Jos haluat suojata arkkusi, k\u00e4yt\u00e4 esim. LWC- tai Lockette-lis\u00e4osaa!", + "shop-creation-cancelled": "&cKaupan luonti peruutettiin.", + "shop-purchase-cancelled": "&cOstaminen peruutettiin.", + "shop-stock-too-low": "&cKaupassa on j\u00e4ljell\u00e4 {0} {1}.", + "you-cant-afford-to-buy": "&cTuote maksaa {0}, mutta sinulla on vain {1}.", + "negative-amount": "&cH\u00f6ps\u00f6! Et voi myyd\u00e4 negatiivisia m\u00e4\u00e4ri\u00e4!", + "not-a-number": "&cSinun tulee antaa numeroarvo.", + "not-a-integer": "&cSinun tulee antaa numeroarvo.", + "player-bought-from-your-store": "&cPelaaja {0} osti kaupastasi {1} {2}.", + "shop-out-of-stock": "&5Kaupastasi koordinaateissa {0}, {1}, {2}, on lopunut {3}.", + "shop-has-no-space": "&cKaupassa on {1} paikkaa tuotteelle {0}.", + "you-dont-have-that-many-items": "&cSinulla on vain {0} {1}", + "the-owner-cant-afford-to-buy-from-you": "&cTuotteen hinta olisi {0}, mutta omistajalla on vain {1}.", + "player-sold-to-your-store": "&aPelaaja {0} myi {1} {2} kauppaasi.", + "shop-out-of-space": "&5Kauppasi koordinaateissa {0}, {1}, {2} on nyt t\u00e4ynn\u00e4.", + "fee-charged-for-price-change": "&aMaksoit {0} vahtaaksesi kaupan hinnan.", + "price-is-now": "&aKaupan uusi hinta on nyt &e{0}&a.", + "thats-not-a-number": "&cEp\u00e4kelpo numero.", + "no-price-given": "&cAnnathan validin hinnan.", + "average-price-nearby": "&aKeskim\u00e4\u00e4r\u00e4inen hinta l\u00e4hettyvill\u00e4: &e{0}", + "shop-has-changed": "&cKauppa, jota yritit k\u00e4ytt\u00e4\u00e4, on muuttanut hintaansa tai muita tietoja sen j\u00e4lkeen kun klikkasit sit\u00e4.", + "shop-not-exist": "&cSiell\u00e4 ei ole kauppaa.", + "nearby-shop-this-way": "&aKauppa on {0} kuutiota kaukana sinusta.", + "no-nearby-shop": "&cKauppoja, jotka myyv\u00e4t tuotetta {0} ei ole l\u00e4hist\u00f6ll\u00e4.", + "buying-more-than-selling": "&c&lVAROITUS: &cSin\u00e4 ostat tuotetta kalliimalla, kun myyt sit\u00e4!", + "not-enough-space": "&cSinulla on tilaa vain {0} tuolle.", + "refill-success": "&aUudelleent\u00e4ytt\u00f6 onnistui!", + "empty-success": "&aTyhjennys onnistui!", + "admin-shop": "AdminKauppa", + "unknown-owner": "Tuntematon", + "owner-bypass-check": "&aVaihto onnistui! (omistat kaupan)", + "reached-maximum-can-create": "&cOlet tehnyt kauppoja jo {0}\/{1}, eli maksimin m\u00e4\u00e4r\u00e4n.", + "restricted-prices": "&cRajatut hinnat tuotteelle {0}: v\u00e4hint\u00e4\u00e4n {1}, enint\u00e4\u00e4n {2}", + "no-enough-money-to-keep-shops": "&cSinulla ei ollut varaa yll\u00e4pit\u00e4\u00e4 kauppojasi. Kaikki kauppasi on nyt poistettu...", + "nothing-to-flush": "&aSinulla ei ole uusia kauppaviestej\u00e4.", + "break-shop-use-supertool": "&eRikot kauppoja k\u00e4ytt\u00e4en tyokalua.", + "failed-to-put-sign": "&cKaupan kyltille ei ole tilaa.", + "failed-to-paste": "&cTietojen lataaminen Pastebiniin ep\u00e4onnistui. Tarkista Internet-yhteystesi ja yrit\u00e4 uudelleen. Palvelimen konsolissa on lis\u00e4tietoja.", + "warn-to-paste": "&eKer\u00e4t\u00e4\u00e4n tietoja Pastebiniin. T\u00e4m\u00e4 vie hetken. &c&lVaroitus:&c tiedot ovat julkisia yhden viikon ajan - ja se saattaa vuotaa sinun palvelimen asetuksia ja salasanoja. Varmista, ett\u00e4 jaat sen vain luotetulle henkil\u00f6kunnalle tai kehitt\u00e4j\u00e4lle.", + "price-too-high": "&cKaupan hinta on liian suuri. Et voi asettaa kaupan hintaa korkeammalle kuin: {0}", + "you-cant-create-shop-in-there": "&cSinulla ei ole oikeutta luoda kauppaa t\u00e4lle alueelle.", + "unknown-player": "&cKohdepelaajaa ei l\u00f6ydetty. Tarkista, ett\u00e4 pelaajan k\u00e4ytt\u00e4j\u00e4nimi on oikein kirjoitettu.", + "shop-staff-cleared": "&cKauppasi henkil\u00f6kunta poistettiin onnistuneesti", + "shop-staff-added": "&aPelaaja {0} lis\u00e4ttiin onnistuneesti kauppasi henkil\u00f6kuntaan!", + "shop-staff-deleted": "&aPelaaja {0} poistettiin onnistuneesti kauppasi henkil\u00f6kunnasta.", + "no-permission-build": "&cEt voi rakentaa kauppaa t\u00e4nne.", + "success-change-owner-to-server": "&aPalvelin omistaa nyt t\u00e4m\u00e4n kaupan", + "flush-finished": "&aViestit p\u00e4ivitettiin onnistuneesti.", + "purchase-failed": "&cOsto ep\u00e4onnistui. Ole yhteydess\u00e4 palvelimen yll\u00e4pitoon.", + "no-pending-action": "&cSinulla ei ole olemassa olevaa toimintopyynt\u00f6\u00e4.", + "permission-denied-3rd-party": "&cSinulla ei ole oikeutta 3:n osapuolen lis\u00e4osaan [{0}].", + "menu": { + "successful-purchase": "&aOnnistuneesti ostettiin:", + "successfully-sold": "&aOnnistuneesti myytiin", + "item-name-and-price": "&e{0} {1} &ahintaan &e{2}", + "sell-tax": "&aMaksoit &e{0} &averoa.", + "sell-tax-self": "&aOmistat t\u00e4m\u00e4n kaupan, joten et maksa veroja.", + "enchants": "&5Lumoukset", + "stored-enchants": "&5Varastoidut lumoukset", + "shop-information": "&aKaupan tiedot", + "owner": "&aOmistaja: {0}", + "item": "&aTuote: &e{0}", + "preview": "&b[esikatsele]", + "space": "&aVapaa tila: &e{0}", + "stock": "&aVarastossa: &e{0}", + "price-per": "&aHinta per &e{0} &a- &e{1}", + "total-value-of-chest": "&aArkun yhteenlaskettu hinta: &e{0}", + "damage-percent-remaining": "&e{0}% &aj\u00e4ljell\u00e4.", + "this-shop-is-buying": "&aT\u00e4m\u00e4 kauppa &a&lOSTAA &atuotteita.", + "this-shop-is-selling": "&aT\u00e4m\u00e4 kauppa &c&lMYY &atavaroita.", + "effects": "&aEfektit: &e{0}", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cOhitetaan QuickShopin lukitus!", + "that-is-locked": "&cT\u00e4m\u00e4 kauppa on lukittu.", + "how-many-buy": "&aKirjoita chattiin kuinka monta haluat &c&lOSTAA&a.", + "how-many-sell": "&aKirjoita chattiin kuinka kappaletta monta haluat &a&lMYYD\u00c4&a. Sinulla on &e{0}&a myyt\u00e4v\u00e4\u00e4 tavaraa.", + "not-allowed-to-create": "&cEt luultavasti voi luoda kauppaa t\u00e4nne.", + "blacklisted-item": "&cT\u00e4m\u00e4 tavara on mustalla listalla. Et luultavasti voi myyd\u00e4 sit\u00e4", + "how-much-to-trade-for": "&aKirjoita chattiin numeroina, mink\u00e4 hinnan haluat asettaa tuotteelle &e{0}&a.", + "command": { + "toggle-unlimited": { + "unlimited": "&aKaupassa on nyt rajattomasti tavaroita", + "limited": "&aKauppa ei ole en\u00e4\u00e4n rajaton" + }, + "no-owner-given": "&cOmistajaa ei ole asetettu. K\u00e4yt\u00e4 &a\/qs setowner &c", + "new-owner": "&aUusi omistaja: &e{0}", + "now-buying": "&aKauppasi &c&lOSTAA&a nyt tuotetta &e{0}", + "now-selling": "&aKauppasi &a&lMYY&a nyt tuotetta &e{0}", + "cleaning": "&aPoistetaan tyhji\u00e4 kauppoja...", + "reloading": "&aLadataan uudelleen...", + "cleaned": "&aPoistettu &e{0}&a kauppaa", + "no-type-given": "&cK\u00e4yt\u00e4: \/qs find ", + "no-amount-given": "&cSummaa ei ole annettu. K\u00e4yt\u00e4 &a\/qs refill &c", + "now-debuging": "&aOnnistuneesti siirrytty kehitt\u00e4j\u00e4tilaan, QuickShop ladataan uudelleen...", + "now-nolonger-debuging": "&aOnnistuneesti siirrytty tuotantotilaan, QuickShop ladataan uudelleen...", + "wrong-args": "&cParametrit eiv\u00e4t t\u00e4sm\u00e4nneet, k\u00e4yt\u00e4 \/qs help katsoaksesi apua", + "description": { + "title": "&aQuickShop-apu", + "unlimited": "&eTekee kaupasta rajattoman", + "setowner": "&eVaihtaa kaupan omistajan", + "owner": "&eVaihtaa kaupan omistajan", + "buy": "&eVaihtaa kaupan &costamaan&e tuotteita", + "sell": "&eVaihtaa kaupan &amyym\u00e4\u00e4n &etuotteita.", + "price": "&eVaihtaa osto tai myynti hinnan yhdest\u00e4 kaupastasi", + "clean": "&ePoistaa kaikki (ladatut) kaupat, jonka varastot ovat tyhj\u00e4t.", + "find": "&eEtsii l\u00e4himm\u00e4n kaupan haluumallesi tavaralle.", + "reload": "&eLataa QuickShopin config.yml tiedoston uudelleen", + "refill": "&eLis\u00e4\u00e4 tietyn m\u00e4\u00e4r\u00e4n tavaroita kauppaan", + "empty": "&eTyhjent\u00e4\u00e4 koko varaston kaupasta", + "debug": "&eVaihtaa kehitt\u00e4j\u00e4tilaan", + "create": "&eLuo uuden kaupan kohdistettuun arkkuun", + "fetchmessage": "&eHae lukematon kaupan viesti", + "info": "&eN\u00e4yt\u00e4 QuickShopin tilastoja", + "paste": "&eLataa automaatisesti palvelimen dataa Pastebiniin", + "staff": "&eHallinnoi kauppasi henkil\u00f6kuntaa", + "remove": "&ePoista kauppa, jota katsot", + "amount": "&eTee toiminto summalla (chat-ongelmia varten)", + "about": "&eN\u00e4yt\u00e4 QuickShop-ohjeistukset", + "help": "&eN\u00e4yt\u00e4 QuickShop-apuselitteet", + "supercreate": "&eLuo kauppa ohittamalla kaikki suojaustarkistukset" + } + }, + "signs": { + "selling": "{0} kpl", + "header": "&l{0}", + "buying": "Ostetaan {0}", + "item": "{0}", + "price": "{0} kpl", + "unlimited": "Rajaton" + }, + "controlpanel": { + "setowner": "&aOmistaja: &b{0} &e[&dvaihda&e]", + "infomation": "&aKaupan asetukset:", + "setowner-hover": "&eVaikuttaisi silt\u00e4, ett\u00e4 haluat vaithaa kaupan omistajaa. Klikkaa!", + "unlimited": "&aRajaton: {0} &e[&dmuuta&e]", + "unlimited-hover": "&eN\u00e4ytt\u00e4isi silt\u00e4 ett\u00e4 haluat muokata kauppaasi, paina ottaaksesi k\u00e4ytt\u00f6\u00f6n tai poistamalla k\u00e4yt\u00f6st\u00e4.", + "mode-selling": "&aKaupan tila: &aMyyd\u00e4\u00e4n &e[&dmuuta&e]", + "mode-selling-hover": "&eN\u00e4ytt\u00e4isi silt\u00e4 ett\u00e4 haluat muokata kauppaasi, paina ottaaksesi k\u00e4ytt\u00f6\u00f6n tai poistamalla k\u00e4yt\u00f6st\u00e4.", + "mode-buying": "&aKaupan tila: &cOstetaan &e[&d&lVaihda&e]", + "mode-buying-hover": "&eN\u00e4ytt\u00e4isi silt\u00e4 ett\u00e4 haluat muokata kauppaa, paina vaihtaaksesi kaupan tila aktiiviseksi tai poistetuksi k\u00e4yt\u00f6st\u00e4.", + "price": "&aHinta: &b{0} &e[&daseta&e]", + "price-hover": "&eN\u00e4ytt\u00e4isi silt\u00e4 ett\u00e4 haluat muokata kauppaa, paina asetaaksesi uusi hinta.", + "refill": "&aT\u00e4ydennys: T\u00e4ydenn\u00e4 kaupan varasto &e[&d&lOK&e]", + "refill-hover": "&eN\u00e4ytt\u00e4isi silt\u00e4 ett\u00e4 haluat muokata kauppaa, paina t\u00e4ydent\u00e4\u00e4ksesi kaupan varasto.", + "empty": "&aTyhjenn\u00e4: Tyhjenn\u00e4 kaupan varasto &e[&d&lOK&e]", + "empty-hover": "&eN\u00e4ytt\u00e4isi silt\u00e4 ett\u00e4 haluat muokata kauppaa, paina tyhjentt\u00e4ksesi kaupan varasto.", + "remove": "&c&l[Poista kauppa]", + "remove-hover": "&ePoista t\u00e4m\u00e4 kauppa klikkaamalla.", + "commands": { + "setowner": "\/qs setowner [Pelaaja]", + "unlimited": "\/qs slientunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [Uusi hinta]", + "refill": "\/qs refill [summa]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a\u2714", + "failed": "&c\u2718" + }, + "tabcomplete": { + "price": "[hinta]", + "range": "[s\u00e4de]", + "amount": "[m\u00e4\u00e4r\u00e4]" + }, + "updatenotify": { + "buttontitle": "[P\u00e4ivit\u00e4 nyt]", + "onekeybuttontitle": "[klikkaa p\u00e4ivitt\u00e4\u00e4ksesi]", + "list": [ + "Versio {0} on jo julkaistu, k\u00e4yt\u00e4t edelleen versiota {1}!", + "Pam! Uusi p\u00e4ivitys {0} on tullut! P\u00e4ivit\u00e4!", + "Yll\u00e4tys! Versio {0} tuli ulos, sin\u00e4 olet versiossa {1}.", + "N\u00e4ytt\u00e4isi silt\u00e4 ett\u00e4 sinun t\u00e4ytyy p\u00e4ivitt\u00e4\u00e4, {0} on p\u00e4ivitetty!", + "Ooops! {0} on julkaistu, sinulla on {1}!", + "Lupaan, ett\u00e4 QS on p\u00e4ivitetty versioon {0}, miksi et p\u00e4ivitt\u00e4isi?", + "Korjataan ja korjataan... Pahoittelen, mutta {0} on p\u00e4ivitetty!", + "Virhe! Ei oikeasti, QS:n uusi versio {0} on julkaistu!", + "OMG! {0} on tullut ulos! Miksi k\u00e4ytt\u00e4t yh\u00e4 {1}?", + "P\u00e4iv\u00e4n uutiset: QuickShop p\u00e4ivittyi versioon {0}!", + "Sinun kannattaisi p\u00e4ivitt\u00e4\u00e4 QS versioon {0}!", + "Hrrr! P\u00e4ivit\u00e4 versioon {0} nyt!", + "Kerron sinulle, ett\u00e4 {0} julkaistaisiin!", + "M\u00e4 oon jo versiossa {0}! P\u00e4ivit\u00e4! S\u00e4 oot viel {1}-versiossa ;)", + "Jeeeeeeee! Uusi p\u00e4ivitys {0} on tullut! P\u00e4ivit\u00e4!", + "Mit\u00e4 ajattelet? {0} on julkaistu! P\u00e4ivit\u00e4!" + ], + "remote-disable-warning": "&cT\u00e4m\u00e4 QuickShop-versio on merkitty toimimattomaksi et\u00e4palvelimelta. T\u00e4m\u00e4 tarkoittaa sit\u00e4, ett\u00e4 MIK\u00c4\u00c4N tai OSA QuickShopin ominaisuuksista ei toimi tai on pahasti vialla. Lataa uusi versio SpigotMC-sivuiltamme: {0}. T\u00e4m\u00e4 varoitusviesti poistuu, eik\u00e4 sp\u00e4mmi konsoliasi, kun p\u00e4ivit\u00e4t t\u00e4m\u00e4n lis\u00e4osan.", + "label": { + "unstable": "[Ep\u00e4vakaa]", + "stable": "[Vakaa]", + "lts": "[LTS]", + "qualityverifyed": "[Laatu]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cKauppasi ({0}) poistettiin, sill\u00e4 sinulla ei ollut varaa yll\u00e4pit\u00e4\u00e4 sit\u00e4!", + "digits-reach-the-limit": "&cOlet saavuttanut desimaalirajan.", + "complete": "&aValmis!" +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/fr.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/fr.json new file mode 100644 index 0000000..db1ff67 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/fr.json @@ -0,0 +1,234 @@ +{ + "translation-author": "Traducteur : &b&liDrunK & &b&lZenCraft", + "translation-version": "Version suport\u00e9e: Reremake", + "translation-contributors": "Contributeurs: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "Langue: Fran\u00e7ais (fr_FR)", + "language-version": "27", + "not-looking-at-shop": "&cAucun coffre de shop trouv\u00e9. Tu dois en regarder un.", + "no-anythings-in-your-hand": "&cTu ne poss\u00e8de aucun item dans ta main.", + "no-permission": "&cTu n'as pas la permission de faire ceci.", + "no-creative-break": "&cTu ne peux pas casser la boutique d'un autre joueur en mode creatif. Utilise le mode survie.", + "no-double-chests": "&cTu ne peux pas cr\u00e9er de boutique avec un double doffre.", + "shop-already-owned": "&cCe coffre est d\u00e9j\u00e0 un coffre de shop.", + "chest-was-removed": "&cLe coffre a \u00e9t\u00e9 supprim\u00e9", + "price-too-cheap": "&cLe prix doit \u00eatre sup\u00e9rieur \u00e0 &e${0}", + "no-price-change": "&cLe prix ne subira aucun changement !", + "you-cant-afford-a-new-shop": "&cLa cr\u00e9ation d'une coffre de shop co\u00fbte {0}.", + "player-bought-from-your-store-tax": "&c{0} a achet\u00e9 {1} {2} dans ta boutique, et tu as pay\u00e9 {3} de taxes.", + "you-cant-afford-to-change-price": "&cCela co\u00fbte {0} de changer le prix de ton coffre de shop.", + "success-created-shop": "&aShop cr\u00e9\u00e9 avec succ\u00e8s.", + "success-removed-shop": "&aCoffre de shop supprim\u00e9 avec succ\u00e8s.", + "shops-arent-locked": "&cSouviens toi que les boutiques ne sont pas prot\u00e9g\u00e9s contre le pillage! Tu dois les verrouiller ou prot\u00e9ger ta zone pour \u00e9viter le vol.", + "shop-creation-cancelled": "&cCr\u00e9ation du shop annul\u00e9.", + "shop-purchase-cancelled": "&cAchat annul\u00e9.", + "shop-stock-too-low": "&cIl ne reste que {0} {1} dans cette boutique.", + "you-cant-afford-to-buy": "&cCette transaction co\u00fbte {0}, mais tu n'as que {1}.", + "negative-amount": "&cTu ne peux pas \u00e9changer une quantit\u00e9 n\u00e9gative !", + "not-a-number": "&cSeul les nombres doivent \u00eatres utilis\u00e9s. Toutefois tu as saisi {0}", + "not-a-integer": "&cSeul les nombres entiers doivent \u00eatres utilis\u00e9s, mais tu as saisi {0}", + "player-bought-from-your-store": "&c{0} a achet\u00e9 {1} {2} dans ta boutique.", + "shop-out-of-stock": "&5Ta boutique aux coordonn\u00e9es {0}, {1}, {2}, est \u00e0 court de {3}", + "shop-has-no-space": "&cCette boutique n'a de la place que pour {0} de plus {1}.", + "you-dont-have-that-many-items": "&cTu ne poss\u00e8de que {0} {1} dans ton inventaire.", + "the-owner-cant-afford-to-buy-from-you": "&cCela co\u00fbte {0} mais le propri\u00e9taire n'a plus que {1}", + "player-sold-to-your-store": "&a{0} \u00e0 vendu {1} {2} dans ta boutique.", + "shop-out-of-space": "&5Ton coffre de shop aux coordonn\u00e9es {0}, {1}, {2}, est plein.", + "fee-charged-for-price-change": "&aTu payera &c{0}&a pour changer le prix.", + "price-is-now": "&aLe nouveau prix de ce coffre de shop est de: &e{0}", + "thats-not-a-number": "&cNombre invalide.", + "no-price-given": "&cMerci de donner un nombre\/chiffre valide.", + "average-price-nearby": "&aPrix moyen aux alentours de: &e{0}", + "shop-has-changed": "&cLe coffre de shop que tu essaye d'utiliser \u00e0 chang\u00e9 depuis que tu as cliqu\u00e9 dessus!", + "shop-not-exist": "&cIl n'y a aucune boutique.", + "nearby-shop-this-way": "&aLe coffre de shop est \u00e0 {0} blocs de toi.", + "no-nearby-shop": "&cAucune boutique trouv\u00e9e dans les alentours", + "buying-more-than-selling": "&cATTENTION: Tu est entrains d'acheter des objets plus cher que tu ne les vends.", + "not-enough-space": "&cIl ne te reste que {0} de place restante pour ceci !", + "refill-success": "&aRe Stock effectu\u00e9", + "empty-success": "&aVid\u00e9 avec succ\u00e8s.", + "admin-shop": "Boutique Admin", + "unknown-owner": "Inconnu", + "owner-bypass-check": "&eV\u00e9rifications \u00e9vit\u00e9es, Echange r\u00e9ussi ! (Tu es propri\u00e9taire de la boutique)", + "reached-maximum-can-create": "&cTu as atteint ton nombre de coffre de shop maximal: {0}\/{1}!", + "restricted-prices": "&cPrix restreints {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cTu n'as plus asseez d'argent pour garder tes coffres de shop.. Tout tes coffres ont \u00e9t\u00e9 supprim\u00e9s.", + "nothing-to-flush": "&aAucun nouveau message de boutique.", + "break-shop-use-supertool": "&eTu as cass\u00e9 la boutique en utilisant le super outil.", + "failed-to-put-sign": "&cIl n'y a pas assez de place autour de la boutique pour placer un panneau d'information.", + "failed-to-paste": "&cErreur lors de l'upload des donn\u00e9es vers PasteBin, verifier la connection internet et r\u00e9\u00e9ssayez. (Voir la console)", + "warn-to-paste": "&eAssemblage de donn\u00e9es et upload vers PasteBin, cela peut prendre un moment. &c&lAttention:&c Les donn\u00e9es sont gard\u00e9es publiques pendant UNE semaine, cela peut faire fuiter la config de votre serveur, assurez vous de la partager \u00e0 des gens de confiances.", + "price-too-high": "&cLe prix est trop haut! Tu ne peux pas mettre un prix sup\u00e9rieur \u00e0 {0} .", + "you-cant-create-shop-in-there": "&cTu n'as pas la permission de cr\u00e9er une boutique \u00e0 cet emplacement!", + "unknown-player": "&cLe joueur cible n'existe pas, merci de v\u00e9rifier le pseudo que tu as entr\u00e9.", + "shop-staff-cleared": "&aTous les g\u00e9rants de ton coffre de shop ont \u00e9t\u00e9 supprim\u00e9s avec succ\u00e8s!", + "shop-staff-added": "&aLe g\u00e9rant {0} \u00e0 \u00e9t\u00e9 ajout\u00e9 \u00e0 ton coffre de shop avec succ\u00e8s!", + "shop-staff-deleted": "&aLe staff {0} \u00e0 \u00e9t\u00e9 supprim\u00e9 de votre boutique avec succ\u00e8s!", + "no-permission-build": "&cTu ne peux pas cr\u00e9er une boutique ici.", + "success-change-owner-to-server": "&aLe propri\u00e9taire de la boutique \u00e0 \u00e9t\u00e9 d\u00e9finit au Serveur avec succ\u00e8s!", + "flush-finished": "&aMessages communiqu\u00e9s avec succ\u00e8s", + "purchase-failed": "&cEchec de l'achat: Erreur interne, veuillez contacter un administrateur du serveur.", + "no-pending-action": "&cTu n'as aucune action en attente", + "permission-denied-3rd-party": "&cPermission refus\u00e9e: plugin tiers [{0}].", + "menu": { + "successful-purchase": "&aAchat r\u00e9ussi:", + "successfully-sold": "&aVente r\u00e9ussie:", + "item-name-and-price": "&e{0} {1} &apour &e{2}", + "sell-tax": "&aTu as pay\u00e9&e{0} &aen taxes.", + "sell-tax-self": "&aCe shop t'appartient donc tu ne payes pas de taxes.", + "enchants": "&5Enchantements", + "stored-enchants": "&5Enchantements Stock\u00e9s", + "shop-information": "&aInformations sur la boutique :", + "owner": "&aPropri\u00e9taire: {0}", + "item": "&aObjet: &e{0}", + "preview": "&b[Pr\u00e9visualisation de l'objet]", + "space": "&aEspace restant: &e{0}", + "stock": "&aStock restant&e{0}", + "price-per": "&aPrix unitaire de &e{0} &a- &e{1}", + "total-value-of-chest": "&aValeur totale du coffre: &e{0}", + "damage-percent-remaining": "&e{0}% &arestant.", + "this-shop-is-buying": "&aCette boutique &dACHETE&a des objets.", + "this-shop-is-selling": "&aCeette boutique &dVEND&a des objets.", + "effects": "&aEffets", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cContournement d'un verrou de QuickShop !", + "that-is-locked": "&cCe shop est verouill\u00e9.", + "how-many-buy": "\u00a7aEntrez le nombre d'items que vous souhaitez \u00a7bACHETER\u00a7a dans le chat. Vous en avez \u00a7e{0}\u00a7a dans votre inventaire. Entrez \u00a7ball\u00a7a pour tous les acheter.", + "how-many-sell": "\u00a7aEntrez le nombre d'items que vous souhaitez \u00a7bVENDRE\u00a7a dans le chat. Vous en avez \u00a7e{0}\u00a7a dans votre inventaire. Entrez \u00a7ball\u00a7a pour tous les vendres.", + "not-allowed-to-create": "&cVous ne pouvez pas cr\u00e9er un shop ici.", + "blacklisted-item": "&cCet item est blacklist\u00e9. Vous ne pouvez pas le vendre.", + "how-much-to-trade-for": "&aEntrez le prix contre lequel vous souhaitez \u00e9changer l'item &e{0}&a dans le chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aCe shop est d\u00e9sormais illimit\u00e9", + "limited": "&aCe shop est d\u00e9sormais limit\u00e9" + }, + "no-owner-given": "&cPas de propri\u00e9taire d\u00e9fini. Utilise &a\/qs setowner &cpour d\u00e9finir un propri\u00e9taire.", + "new-owner": "&aNouveau propri\u00e9taire: &e{0}", + "now-buying": "&dACHETE &aactuellement des &e{0}", + "now-selling": "&bVEND &aactuellement des &e{0}", + "cleaning": "&aSuppression des shops avec 0 de stock.", + "reloading": "&aRechargement...", + "cleaned": "&e{0} &acoffres de shop ont \u00e9t\u00e9 supprim\u00e9s.", + "no-type-given": "&cUtilisation: \/qs find ", + "no-amount-given": "&cAucun montant donn\u00e9. Utilise &a\/qs refill &c", + "now-debuging": "&aPassage r\u00e9ussi en mode d\u00e9veloppeur. Rechargement de QuickShop...", + "now-nolonger-debuging": "&aPassage r\u00e9ussi en mode production. Rechargement de QuickShop...", + "wrong-args": "&cLes param\u00e8tres ne correspondent pas. Utilise \/qs help pour v\u00e9rifier l'aide d'utilisation.", + "description": { + "title": "&aAide QuickShop", + "unlimited": "&eRendre un shop illimit\u00e9", + "setowner": "&eChange le propri\u00e9taire du shop", + "owner": "&eChange le propri\u00e9taire du shop", + "buy": "&eTransforme le coffre de shop en mode &dACHAT", + "sell": "&eTransforme le coffre de shop en mode &bVENTE", + "price": "&eChange le prix d'achat\/vente d'un de tes coffres de shop.", + "clean": "&eSupprime tout les coffres charg\u00e9s ayant 0 de stock.", + "find": "&eLocalise le coffre de shop le plus proche d'un type sp\u00e9cifique.", + "reload": "&eRecharge le fichier config.yml pour QuickShop", + "refill": "&eAjoute un nombre donn\u00e9 d'objets \u00e0 un shop.", + "empty": "&eRetire tout le stock d'un coffre de shop.", + "debug": "&ePasser en mode d\u00e9veloppeur", + "create": "&eCr\u00e9e un nouveau shop au coffre cible", + "fetchmessage": "&eR\u00e9cup\u00e9rer les messages du shop non lus", + "info": "&eAfficher les statistiques QuickShop", + "paste": "&eT\u00e9l\u00e9chargement automatique des donn\u00e9es du serveur vers Pastebin", + "staff": "&eG\u00e9rer les g\u00e9rants de ton coffre de shop", + "remove": "&eSupprime le coffre de shop que tu regarde", + "amount": "&eEx\u00e9cuter les actions avec montant(Pour le probl\u00e8me du plugin de chat)", + "about": "&eA propos de QuickShop", + "help": "&eAfficher l'aide QuickShop", + "supercreate": "&eCr\u00e9er un coffre de shop en contournant tous les contr\u00f4les de protection" + } + }, + "signs": { + "selling": "Vente {0}", + "header": "&c{0}", + "buying": "Achat {0}", + "item": "{0}", + "price": "{0} l'unit\u00e9", + "unlimited": "Illimit\u00e9" + }, + "controlpanel": { + "setowner": "&aPropri\u00e9taire: &b{0} &e[&dChanger&e]", + "infomation": "&aPanneau de controle du shop:", + "setowner-hover": "&eClique pour changer le propri\u00e9taire.", + "unlimited": "&aIllimit\u00e9: {0} &e[&dChanger&e]", + "unlimited-hover": "&eClique pour d\u00e9finir le shop comme illimit\u00e9.", + "mode-selling": "&aMode du shop: &bVENTE &e[&dChanger&e]", + "mode-selling-hover": "&aClique pour convertir le shop en mode achat.", + "mode-buying": "&aMode du shop: &bACHAT &e[&dChanger&e]", + "mode-buying-hover": "&eClique pour convertir le shop en mode vente.", + "price": "&aPrix: &b{0} &e[&d&lD\u00e9finir&e]", + "price-hover": "&eClique pour d\u00e9finir un nouveau prix au coffre de shop.", + "refill": "&aR\u00e9approvisionnement: &e[&d&lR\u00e9approvisionner&e]", + "refill-hover": "&eClique pour r\u00e9approvisionner le shop.", + "empty": "&aVidange du shop: &e[&d&lVider&e]", + "empty-hover": "&eClique pour vider tout les objets du shop.", + "remove": "&c&l[Supprimer le shop]", + "remove-hover": "&eClique pour supprimer ce coffre de shop.", + "commands": { + "setowner": "\/qs setowner [Pseudonyme]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [Nouveau prix]", + "refill": "\/qs refill [Quantit\u00e9]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a\u2714", + "failed": "&c\u2718" + }, + "tabcomplete": { + "price": "[prix]", + "range": "[distance]", + "amount": "[quantit\u00e9]" + }, + "updatenotify": { + "buttontitle": "[Mettre \u00e0 jour]", + "onekeybuttontitle": "[Mise \u00e0 jour instantan\u00e9e]", + "list": [ + "{0} a \u00e9t\u00e9 publi\u00e9e. Vous utilisez encore la version {1} !", + "BOUM! Nouvelle mise \u00e0 jour {0} disponible !", + "Surprise! La mise \u00e0 jour {0} est sortie. Vous \u00eates actuellement sur la version {1}", + "Visiblement vous avez besoin d'une mise \u00e0 jour... La version {0} a \u00e9t\u00e9 publi\u00e9e !", + "OUPS ! La version {0} a d\u00e9j\u00e0 \u00e9t\u00e9 publi\u00e9e... Vous \u00eates sur la version {1} !", + "Je vous jure, QuickShop a \u00e9t\u00e9 mis \u00e0 jour vers la version {0}, pourquoi vous ne l'avez pas mis \u00e0 jour?", + "R\u00e9parer et r\u00e9... D\u00e9sol\u00e9 {0} est sortie !", + "Err! Non, ceci n'est pas une erreur. {0} viens d'\u00eatre publi\u00e9e !", + "OH MON DIEU ! {0} est disponible ! Pourquoi utilisez vous encore {1} ?", + "Nouveaut\u00e9 de la journ\u00e9e: QuickShop a \u00e9t\u00e9 mis \u00e0 jour en {0}", + "Plugin K.I.A, vous devez mettre \u00e0 jour {0}!", + "Fuze lance la mise \u00e0 jour {0}, enregistrez la mise \u00e0 jour!", + "Il y a une mise \u00e0 jour commandant, {0} viens de sortir!", + "Regarde mon style --- {0} mise \u00e0 jour, tu as toujours la version {1}", + "Ahhhhhhh! Nouvelle mise \u00e0 jour {0}!", + "Qu'est-ce que tu penses? {0} Une nouvelle mise \u00e0 jour publi\u00e9e!" + ], + "remote-disable-warning": "&cCette version de QuickShop a \u00e9t\u00e9 d\u00e9sign\u00e9e comme d\u00e9sactiv\u00e9e par le serveur distant. Cela signifie que cette version peux contenir de s\u00e9rieux probl\u00e8mes et bugs. Plus de d\u00e9tails sur notre page SpigotMC: {0}. Cet avertissement apparaitra dans votre console jusqu'\u00e0 ce que vous utilisiez une version stable de QuickShop. Ceci n'affecte pas le fonctionnement de votre serveur.", + "label": { + "unstable": "[Instable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Qualit\u00e9]", + "github": "[GitHub]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cTon coffre de shop aux coordonn\u00e9es {0} a \u00e9t\u00e9 supprim\u00e9 car tu n'avais plus assez d'argent pour le garder !", + "digits-reach-the-limit": "&cTu as atteint la limite de d\u00e9cimales dans le prix.", + "complete": "&aAction effectu\u00e9e" +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/it.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/it.json new file mode 100644 index 0000000..de415c4 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/it.json @@ -0,0 +1,234 @@ +{ + "translation-author": "PapaPinuXIo", + "translation-version": "1.15.1Pro", + "translation-contributors": "Rightdenied", + "translation-country": "Language Zone: English (it_US)", + "language-version": "27", + "not-looking-at-shop": "&cNon \u00e8 stato trovato nessun QuickShop, devi guardarne uno", + "no-anythings-in-your-hand": "&cNon hai nulla in mano.", + "no-permission": "&c Non hai i permessi per questo.", + "no-creative-break": "&cPuoi rompere i negozi solo in modalit\u00e0 sopravvivenza.", + "no-double-chests": "&cNon puoi creare un negozio Doppia Cassa.", + "shop-already-owned": "&cQuesto gi\u00e0 \u00e8 un negozio.", + "chest-was-removed": "&cIl cartello \u00e8 stato rimosso.", + "price-too-cheap": "&cIl prezzo deve essere superiore a &e ${0}", + "no-price-change": "&cQuesto non comporta un cambio di prezzo.", + "you-cant-afford-a-new-shop": "&cIl prezzo per un nuovo negzio \u00e8 di {0}", + "player-bought-from-your-store-tax": " &c{0} Ha acquistato {1} {2} dal tuo negozio e hai pagato {3} di tasse.", + "you-cant-afford-to-change-price": "&c{0} comprato {1} {2} dal tuo negozio, e tu hai pagato {3} in tasse.", + "success-created-shop": "&cNegozio creato", + "success-removed-shop": "&cNegozio rimosso", + "shops-arent-locked": "&cRICORDA, i negozi NON sono protetti dai furti! Se tu volessi fermare i ladri bloccali con LWC, Lockette, etc!", + "shop-creation-cancelled": "&cCreazione del negozio cancellata", + "shop-purchase-cancelled": "&cAcquisto del negozio cancellato", + "shop-stock-too-low": "&cIl negozio ha solo {0} {1} sinstra", + "you-cant-afford-to-buy": "&cCosta {0}, ma hai solo {1}", + "negative-amount": "&c Hops! non \u00e8 possibile scambiare importi negativi", + "not-a-number": "&cDevi inserire una cifra, inserisci{0}", + "not-a-integer": "&cDevi inserire una cifra intera, inserisci {0}", + "player-bought-from-your-store": "&c{0}Ha acquistato {1} {2} dal tuo negozio", + "shop-out-of-stock": "&5Il tuo negosio su {0}, {1}, {2}, ha esaurito {3}", + "shop-has-no-space": "&cIl negozio ha spazio solo per {0} in pi\u00f9 {1}.", + "you-dont-have-that-many-items": "&cHai solo {0}{1}.", + "the-owner-cant-afford-to-buy-from-you": "&cL'oggetto che vuoi vendere cosa {0} ma il proprietario ha solo {1}", + "player-sold-to-your-store": "e un {0} ha venduto {1} {2} al tuo negozio", + "shop-out-of-space": "&5Il tuo negozio a {0}, {1}, {2} \u00e8 Pieno", + "fee-charged-for-price-change": "&aPer modificare il prezzo si paga &c{0}", + "price-is-now": "&aIl nuovo prezzo del negozio \u00e8 &e {0}", + "thats-not-a-number": "&cNon hai inserito nessuna cifra", + "no-price-given": "&cInserisci una cifra Valida", + "average-price-nearby": "&aPrezzo medio nelle vicinanze: &e{0}", + "shop-has-changed": "&cIl negozio che stai utilizzando \u00e8 cambiato dall'ultima visita", + "shop-not-exist": "&cNon c'era nessun negozio", + "nearby-shop-this-way": "&aIl negozio \u00e8 a {0} isolati da te", + "no-nearby-shop": "&cNon c'\u00e8 nessun negozio {0} nelle tue vicinanze", + "buying-more-than-selling": "&cATTENZIONE &aIl prezzo d'acquisto \u00e8 pi\u00f9 alto del prezzo di vendita", + "not-enough-space": "&c Hai spazio solo per {0} in pi\u00f9!", + "refill-success": "&aRifila il successo", + "empty-success": "&aSuccesso vuoto", + "admin-shop": "&6&LNegozio Admin", + "unknown-owner": "&2Anonimo", + "owner-bypass-check": "&eHai bypassato tutti i controlli! Ora sei il proprietario del negozio", + "reached-maximum-can-create": "&cHai raggiunto il limite, possiedi {0} su {1}negozi", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a\u2714", + "failed": "&c\u2718" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!" +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/ja.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/ja.json new file mode 100644 index 0000000..55cc75b --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/ja.json @@ -0,0 +1,234 @@ +{ + "translation-author": "&c&l\u7ffb\u8a33\u8005: &b&lKumaisu", + "translation-version": "&c&l\u30b5\u30dd\u30fc\u30c8\u30d0\u30fc\u30b8\u30e7\u30f3: &b&lReremake", + "translation-contributors": "&c&l\u8ca2\u732e\u8005: &b&lTimtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "&c&l\u8a00\u8a9e\u570f: &b&l\u65e5\u672c\u8a9e (ja_JP)", + "language-version": "27", + "not-looking-at-shop": "&cQuickShop\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u898b\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002", + "no-anythings-in-your-hand": "&c\u3042\u306a\u305f\u306e\u624b\u306b\u306f\u4f55\u3082\u3042\u308a\u307e\u305b\u3093\u3002", + "no-permission": "&c\u3042\u306a\u305f\u306b\u306f\u8a31\u53ef\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002", + "no-creative-break": "&c\u30af\u30ea\u30a8\u30a4\u30c6\u30a3\u30d6\u30e2\u30fc\u30c9\u3067\u4ed6\u306e\u30d7\u30ec\u30a4\u30e4\u30fc\u30b7\u30e7\u30c3\u30d7\u3092\u58ca\u3059\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002 \u4ee3\u308f\u308a\u306b\u30b5\u30d0\u30a4\u30d0\u30eb\u3092\u4f7f\u7528\u3057\u3066\u304f\u3060\u3055\u3044\u3002", + "no-double-chests": "&c\u30c0\u30d6\u30eb\u30c1\u30a7\u30b9\u30c8\u30b7\u30e7\u30c3\u30d7\u3092\u4f5c\u6210\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3002", + "shop-already-owned": "&c\u3059\u3067\u306b\u30b7\u30e7\u30c3\u30d7\u3067\u3059\u3002", + "chest-was-removed": "&c\u30c1\u30a7\u30b9\u30c8\u304c\u524a\u9664\u3055\u308c\u307e\u3057\u305f\u3002", + "price-too-cheap": "&c\u4fa1\u683c\u306f&e${0}&c\u4ee5\u4e0a\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002", + "no-price-change": "&c\u4fa1\u683c\u5909\u66f4\u3067\u304d\u307e\u305b\u3093\uff01", + "you-cant-afford-a-new-shop": "&c\u65b0\u3057\u3044\u30b7\u30e7\u30c3\u30d7\u3092\u4f5c\u6210\u3059\u308b\u306b\u306f{0}\u304b\u304b\u308a\u307e\u3059\u3002", + "player-bought-from-your-store-tax": "&c{0} \u306f {1} {2} \u3092\u30b7\u30e7\u30c3\u30d7\u304b\u3089\u8cfc\u5165\u3057 {3} \u3092\u7a0e\u3067\u652f\u6255\u3044\u307e\u3057\u305f\u3002", + "you-cant-afford-to-change-price": "&c\u30b7\u30e7\u30c3\u30d7\u3067\u4fa1\u683c\u3092\u5909\u66f4\u3059\u308b\u306b\u306f {0} \u304b\u304b\u308a\u307e\u3059\u3002", + "success-created-shop": "&a\u30b7\u30e7\u30c3\u30d7\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\u3002", + "success-removed-shop": "&a\u30b7\u30e7\u30c3\u30d7\u3092\u524a\u9664\u3057\u307e\u3057\u305f\u3002", + "shops-arent-locked": "&c\u30b7\u30e7\u30c3\u30d7\u306f\u4fdd\u8b77\u3055\u308c\u3066\u3044\u307e\u305b\u3093\uff01\u4fdd\u8b77\u304c\u5fc5\u8981\u306a\u5834\u5408\u306f\u3001LWC\u3084Lockette\u306a\u3069\u3067\u30ed\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044\uff01", + "shop-creation-cancelled": "&c\u30b7\u30e7\u30c3\u30d7\u306e\u4f5c\u6210\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u307e\u3057\u305f\u3002", + "shop-purchase-cancelled": "&c\u8cfc\u5165\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u307e\u3057\u305f\u3002", + "shop-stock-too-low": "&c\u30b7\u30e7\u30c3\u30d7\u306b\u306f {0} {1} \u3057\u304b\u6b8b\u3063\u3066\u3044\u307e\u305b\u3093", + "you-cant-afford-to-buy": "&c\u8cbb\u7528\u306f {0} \u3067\u3059\u304c\u3001{1} \u3057\u304b\u3042\u308a\u307e\u305b\u3093\u3002", + "negative-amount": "&c\u30de\u30a4\u30ca\u30b9\u91cf\u3092\u53d6\u5f15\u3067\u304d\u307e\u305b\u3093", + "not-a-number": "&c\u6570\u5024\u306e\u307f\u304c\u53ef\u80fd\u3067\u3059\u304c {0} \u3092\u5165\u529b\u3057\u3066\u3044\u307e\u3059", + "not-a-integer": "&c\u6574\u6570\u306e\u307f\u304c\u53ef\u80fd\u3067\u3059\u304c {0} \u3092\u5165\u529b\u3057\u3066\u3044\u307e\u3059", + "player-bought-from-your-store": "&c{0} \u306f\u30b7\u30e7\u30c3\u30d7\u304b\u3089 {1} {2} \u3092\u8cfc\u5165\u3057\u307e\u3057\u305f\u3002", + "shop-out-of-stock": "&5{0}\u3001{1}\u3001{2} \u306e\u30b7\u30e7\u30c3\u30d7\u3067 {3} \u304c\u306a\u304f\u306a\u308a\u307e\u3057\u305f", + "shop-has-no-space": "&c\u30b7\u30e7\u30c3\u30d7\u306b\u306f {0} \u500b\u4ee5\u4e0a {1} \u500b\u5206\u306e\u30b9\u30da\u30fc\u30b9\u3057\u304b\u3042\u308a\u307e\u305b\u3093", + "you-dont-have-that-many-items": "&c{0} {1} \u3057\u304b\u3042\u308a\u307e\u305b\u3093", + "the-owner-cant-afford-to-buy-from-you": "&c{0} \u5fc5\u8981\u3067\u3059\u304c {1} \u3057\u304b\u3042\u308a\u307e\u305b\u3093", + "player-sold-to-your-store": "&a{0} \u304c\u3042\u306a\u305f\u306e\u30b7\u30e7\u30c3\u30d7\u306b {1} {2} \u3092\u8ca9\u58f2\u3057\u307e\u3057\u305f", + "shop-out-of-space": "&5{0}, {1}, {2} \u306e\u30b7\u30e7\u30c3\u30d7\u306f\u4e00\u676f\u3067\u3059", + "fee-charged-for-price-change": "&a\u4fa1\u683c\u5909\u66f4\u306e\u305f\u3081 &c{0}&a \u3092\u652f\u6255\u3044\u307e\u3057\u305f", + "price-is-now": "&a\u65b0\u3057\u3044\u4fa1\u683c\u306f &e{0} &a\u3067\u3059", + "thats-not-a-number": "&c\u7121\u52b9\u306a\u756a\u53f7\u3067\u3059", + "no-price-given": "&c\u6709\u52b9\u306a\u4fa1\u683c\u3092\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044", + "average-price-nearby": "&a\u8fd1\u304f\u306e\u5e73\u5747\u4fa1\u683c : &e{0}", + "shop-has-changed": "&c\u30af\u30ea\u30c3\u30af\u3057\u305f\u306e\u3067\u4f7f\u304a\u3046\u3068\u3057\u305f\u30b7\u30e7\u30c3\u30d7\u304c\u5909\u308f\u308a\u307e\u3057\u305f", + "shop-not-exist": "&c\u30b7\u30e7\u30c3\u30d7\u304c\u3042\u308a\u307e\u305b\u3093\u3067\u3057\u305f", + "nearby-shop-this-way": "&a\u30b7\u30e7\u30c3\u30d7\u306f {0} \u30d6\u30ed\u30c3\u30af\u96e2\u308c\u3066\u3044\u307e\u3059", + "no-nearby-shop": "&c\u8fd1\u304f\u306b {0} \u3068\u4e00\u81f4\u3059\u308b\u30b7\u30e7\u30c3\u30d7\u306f\u3042\u308a\u307e\u305b\u3093", + "buying-more-than-selling": "&c\u8b66\u544a : \u58f2\u3063\u3066\u3044\u308b\u30a2\u30a4\u30c6\u30e0\u3088\u308a\u3082\u591a\u304f\u3092\u8cb7\u3063\u3066\u3044\u307e\u3059", + "not-enough-space": "&c{0} \u500b\u5206\u306e\u30b9\u30da\u30fc\u30b9\u3057\u304b\u3042\u308a\u307e\u305b\u3093", + "refill-success": "&aRefill \u6210\u529f", + "empty-success": "&aEmpty \u6210\u529f", + "admin-shop": "\u30a2\u30c9\u30df\u30f3\u30b7\u30e7\u30c3\u30d7", + "unknown-owner": "\u4e0d\u660e", + "owner-bypass-check": "&e\u5168\u3066\u306e\u30c1\u30a7\u30c3\u30af\u3092\u30d0\u30a4\u30d1\u30b9\u3001\u53d6\u5f15\u6210\u529f\uff08\u3042\u306a\u305f\u306f\u30b7\u30e7\u30c3\u30d7\u30aa\u30fc\u30ca\u30fc\u3067\u3059\uff09", + "reached-maximum-can-create": "&c\u3059\u3067\u306b\u6700\u5927 {0} \/ {1} \u306e\u30b7\u30e7\u30c3\u30d7\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f", + "restricted-prices": "&c{0} \u306e\u5236\u9650\u4fa1\u683c : \u6700\u5c0f {1} , \u6700\u5927 {2}", + "no-enough-money-to-keep-shops": "&c\u30b7\u30e7\u30c3\u30d7\u3092\u7dad\u6301\u3059\u308b\u306e\u306b\u5341\u5206\u306a\u8cc7\u91d1\u304c\u3042\u308a\u307e\u305b\u3093\u306e\u3067\u5168\u3066\u306e\u30b7\u30e7\u30c3\u30d7\u304c\u524a\u9664\u3055\u308c\u307e\u3057\u305f", + "nothing-to-flush": "&a\u65b0\u3057\u3044\u30b7\u30e7\u30c3\u30d7\u30e1\u30c3\u30bb\u30fc\u30b8\u306f\u3042\u308a\u307e\u305b\u3093\u3067\u3057\u305f", + "break-shop-use-supertool": "&eSuperTool \u3092\u4f7f\u3063\u3066\u30b7\u30e7\u30c3\u30d7\u3092\u58ca\u3059\u4e8b\u304c\u3067\u304d\u307e\u3059", + "failed-to-put-sign": "&c\u30b7\u30e7\u30c3\u30d7\u306e\u5468\u308a\u306b\u60c5\u5831\u770b\u677f\u3092\u914d\u7f6e\u3059\u308b\u306e\u306b\u5341\u5206\u306a\u30b9\u30da\u30fc\u30b9\u304c\u3042\u308a\u307e\u305b\u3093\u3002", + "failed-to-paste": "&cPastebin \u3078\u306e\u30c7\u30fc\u30bf\u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u3092\u78ba\u8a8d\u3057\u3066\u3001\u3082\u3046\u4e00\u5ea6\u304a\u8a66\u3057\u304f\u3060\u3055\u3044\u3002\uff08\u8a73\u7d30\u306b\u3064\u3044\u3066\u306f\u30b3\u30f3\u30bd\u30fc\u30eb\u3092\u3054\u89a7\u304f\u3060\u3055\u3044\uff09", + "warn-to-paste": "&e\u30c7\u30fc\u30bf\u3092\u53ce\u96c6\u3057\u3066Pastebin\u306b\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3059\u308b\u306b\u306f\u3001\u3057\u3070\u3089\u304f\u6642\u9593\u304c\u304b\u304b\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002&c&l\u8b66\u544a&c\u3001\u30c7\u30fc\u30bf\u306f1\u9031\u9593\u516c\u958b\u3055\u308c\u307e\u3059\u3002\u30b5\u30fc\u30d0\u30fc\u8a2d\u5b9a\u3084\u305d\u306e\u4ed6\u306e\u6a5f\u5bc6\u60c5\u5831\u304c\u6f0f\u6d29\u3059\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002&l\u4fe1\u983c\u3067\u304d\u308b\u30b9\u30bf\u30c3\u30d5\/\u958b\u767a\u8005\u306b\u306e\u307f\u9001\u4fe1\u3059\u308b\u3088\u3046\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002", + "price-too-high": "&c\u30b7\u30e7\u30c3\u30d7\u306e\u4fa1\u683c\u304c\u9ad8\u3059\u304e\u307e\u3059\uff01 {0} \u3088\u308a\u9ad8\u3044\u4fa1\u683c\u306e\u30b7\u30e7\u30c3\u30d7\u306f\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\u3002", + "you-cant-create-shop-in-there": "&c\u3053\u306e\u5834\u6240\u306b\u30b7\u30e7\u30c3\u30d7\u3092\u4f5c\u6210\u3059\u308b\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093\u3002", + "unknown-player": "&c\u76ee\u7684\u306e\u30d7\u30ec\u30fc\u30e4\u30fc\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\u3002\u5165\u529b\u3057\u305f\u30e6\u30fc\u30b6\u30fc\u540d\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002", + "shop-staff-cleared": "&a\u30b7\u30e7\u30c3\u30d7\u306e\u5168\u3066\u306e\u30b9\u30bf\u30c3\u30d5\u3092\u524a\u9664\u3057\u307e\u3057\u305f\u3002", + "shop-staff-added": "&a\u30b7\u30e7\u30c3\u30d7\u30b9\u30bf\u30c3\u30d5\u306b {0} \u3092\u8ffd\u52a0\u3057\u307e\u3057\u305f\u3002", + "shop-staff-deleted": "&a\u30b7\u30e7\u30c3\u30d7\u30b9\u30bf\u30c3\u30d5\u304b\u3089 {0} \u3092\u524a\u9664\u3057\u307e\u3057\u305f\u3002", + "no-permission-build": "&c\u3053\u3053\u3067\u306f\u30b7\u30e7\u30c3\u30d7\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\u3002", + "success-change-owner-to-server": "&a\u30b7\u30e7\u30c3\u30d7\u306e\u6240\u6709\u8005\u3092\u30b5\u30fc\u30d0\u30fc\u306b\u8a2d\u5b9a\u3057\u307e\u3057\u305f\u3002", + "flush-finished": "&a\u672a\u8aad\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u53d6\u308a\u51fa\u3057\u306b\u6210\u529f\u3057\u307e\u3057\u305f", + "purchase-failed": "&c\u8cfc\u5165\u306b\u5931\u6557\u3057\u307e\u3057\u305f\uff1a\u5185\u90e8\u30a8\u30e9\u30fc\u3002\u30b5\u30fc\u30d0\u30fc\u7ba1\u7406\u8005\u306b\u9023\u7d61\u3057\u3066\u304f\u3060\u3055\u3044\u3002", + "no-pending-action": "&c\u4fdd\u7559\u4e2d\u306e\u30a2\u30af\u30b7\u30e7\u30f3\u306f\u3042\u308a\u307e\u305b\u3093", + "permission-denied-3rd-party": "&c\u30a2\u30af\u30bb\u30b9\u62d2\u5426: \u30b5\u30fc\u30c9\u30d1\u30fc\u30c6\u30a3\u306e\u30d7\u30e9\u30b0\u30a4\u30f3 [{0}]", + "menu": { + "successful-purchase": "&a\u8cfc\u5165\u306b\u6210\u529f\u3057\u307e\u3057\u305f :", + "successfully-sold": "&a\u58f2\u5374\u306b\u6210\u529f\u3057\u307e\u3057\u305f :", + "item-name-and-price": "&e{0} {1} &a\u3092 &e{2}", + "sell-tax": "&a\u7a0e\u3068\u3057\u3066 &e{0} &a\u3092\u652f\u6255\u3044\u307e\u3057\u305f", + "sell-tax-self": "&a\u3053\u306e\u30b7\u30e7\u30c3\u30d7\u306e\u6240\u6709\u8005\u306a\u306e\u3067\u7a0e\u652f\u6255\u306f\u3042\u308a\u307e\u305b\u3093", + "enchants": "&5\u30a8\u30f3\u30c1\u30e3\u30f3\u30c8", + "stored-enchants": "&5\u30a8\u30f3\u30c1\u30e3\u30f3\u30c8\u4fdd\u7ba1", + "shop-information": "&a\u30b7\u30e7\u30c3\u30d7\u60c5\u5831 :", + "owner": "&a\u6240\u6709\u8005 : {0}", + "item": "&a\u30a2\u30a4\u30c6\u30e0 : &e{0}", + "preview": "&b[\u30a2\u30a4\u30c6\u30e0\u95b2\u89a7]", + "space": "&a\u7a7a\u304d : &e{0}", + "stock": "&a\u5728\u5eab : &e{0}", + "price-per": "&a\u5358\u4fa1 : &e{0} &a- &e{1}", + "total-value-of-chest": "&a\u30c1\u30a7\u30b9\u30c8\u306e\u5408\u8a08\u984d : &e{0}", + "damage-percent-remaining": "&a\u6b8b\u308a &e{0}%", + "this-shop-is-buying": "&a\u3053\u306e\u30b7\u30e7\u30c3\u30d7\u306f &d\u8ca9\u58f2&a \u3067\u3059", + "this-shop-is-selling": "&a\u3053\u306e\u30b7\u30e7\u30c3\u30d7\u306f &b\u8cb7\u53d6&a \u3067\u3059", + "effects": "&a\u52b9\u679c", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cQuickShop\u30ed\u30c3\u30af\u3092\u30d0\u30a4\u30d1\u30b9\u3057\u307e\u3059\uff01", + "that-is-locked": "&c\u30b7\u30e7\u30c3\u30d7\u306f\u30ed\u30c3\u30af\u3055\u308c\u3066\u3044\u307e\u3059\u3002", + "how-many-buy": "&a\u30c1\u30e3\u30c3\u30c8\u3067&b\u8cfc\u5165&a\u3057\u305f\u3044\u6570\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002&e{0}&a\u3092\u8cfc\u5165\u3067\u304d\u307e\u3059\u3002&ball&a\u3067\u5168\u3066\u8cfc\u5165", + "how-many-sell": "&a\u30c1\u30e3\u30c3\u30c8\u3067&d\u8ca9\u58f2&a\u3057\u305f\u3044\u6570\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002&e{0}&a\u6301\u3063\u3066\u3044\u307e\u3059\u3002&ball&a\u3067\u5168\u3066\u8ca9\u58f2", + "not-allowed-to-create": "&c\u3042\u306a\u305f\u306f\u3053\u3053\u3067\u30b7\u30e7\u30c3\u30d7\u3092\u4f5c\u308b\u4e8b\u304c\u3067\u304d\u307e\u305b\u3093", + "blacklisted-item": "&c\u305d\u306e\u30a2\u30a4\u30c6\u30e0\u306f\u30d6\u30e9\u30c3\u30af\u30ea\u30b9\u30c8\u306b\u8f09\u3063\u3066\u3044\u307e\u3059\u3002\u58f2\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093", + "how-much-to-trade-for": "&a\u30c1\u30e3\u30c3\u30c8\u3067&e {0} &a\u3092\u53d6\u5f15\u3059\u308b\u91d1\u984d\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002", + "command": { + "toggle-unlimited": { + "unlimited": "&a\u30b7\u30e7\u30c3\u30d7\u306f\u7121\u5236\u9650\u306b\u306a\u308a\u307e\u3057\u305f", + "limited": "&a\u30b7\u30e7\u30c3\u30d7\u306f\u5236\u9650\u3055\u308c\u3066\u3044\u307e\u3059" + }, + "no-owner-given": "&c\u6240\u6709\u8005\u304c\u3042\u308a\u307e\u305b\u3093\u3002&a\/qs setowner <\u30d7\u30ec\u30a4\u30e4\u30fc\u540d> &c\u3067\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044", + "new-owner": "&a\u65b0\u3057\u3044\u6240\u6709\u8005 : &e{0}", + "now-buying": "&a\u73fe\u5728 &d\u8cb7\u53d6 &e{0}", + "now-selling": "&a\u73fe\u5728 &b\u8ca9\u58f2 &e{0}", + "cleaning": "&a\u5728\u5eab\u30bc\u30ed\u306e\u30b7\u30e7\u30c3\u30d7\u3092\u524a\u9664\u3057\u307e\u3059", + "reloading": "&a\u30ea\u30ed\u30fc\u30c9\u4e2d...", + "cleaned": "&e{0}&a \u30b7\u30e7\u30c3\u30d7\u3092\u524a\u9664\u3057\u307e\u3057\u305f\u3002", + "no-type-given": "&c\u4f7f\u7528\u6cd5: \/qs find <\u30a2\u30a4\u30c6\u30e0\u540d>", + "no-amount-given": "&c\u6570\u304c\u3042\u308a\u307e\u305b\u3093\u3002&a\/qs refill <\u500b\u6570> &c\u3092\u4f7f\u3063\u3066\u304f\u3060\u3055\u3044", + "now-debuging": "&a\u958b\u767a\u8005\u30e2\u30fc\u30c9\u306b\u5207\u308a\u66ff\u3048\u6210\u529f\u3001QuickShop\u3092\u30ea\u30ed\u30fc\u30c9\u3057\u3066\u3044\u307e\u3059\u3002", + "now-nolonger-debuging": "&a\u30d7\u30ed\u30c0\u30af\u30b7\u30e7\u30f3\u30e2\u30fc\u30c9\u306b\u5207\u308a\u66ff\u3048\u6210\u529f\u3001QuickShop\u3092\u30ea\u30ed\u30fc\u30c9\u3057\u3066\u3044\u307e\u3059\u3002", + "wrong-args": "&c\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u304c\u4e00\u81f4\u3057\u307e\u305b\u3093\u3002\/qs help \u3092\u4f7f\u7528\u3057\u3066\u30d8\u30eb\u30d7\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&e\u30b7\u30e7\u30c3\u30d7\u3092\u7121\u5236\u9650\u306b\u3057\u307e\u3059\u3002", + "setowner": "&e\u30b7\u30e7\u30c3\u30d7\u306e\u6240\u6709\u8005\u3092\u5909\u66f4\u3057\u307e\u3059\u3002", + "owner": "&e\u30b7\u30e7\u30c3\u30d7\u306e\u6240\u6709\u8005\u3092\u5909\u66f4", + "buy": "&e\u30b7\u30e7\u30c3\u30d7\u3092&d\u8cb7\u53d6&e\u30e2\u30fc\u30c9\u306b\u5909\u66f4\u3057\u307e\u3059", + "sell": "&e\u30b7\u30e7\u30c3\u30d7\u3092&b\u8ca9\u58f2&e\u30e2\u30fc\u30c9\u306b\u5909\u66f4\u3057\u307e\u3059", + "price": "&e\u3044\u305a\u308c\u304b\u306e\u30b7\u30e7\u30c3\u30d7\u306e\u8cfc\u5165\/\u8ca9\u58f2\u4fa1\u683c\u3092\u5909\u66f4\u3057\u307e\u3059", + "clean": "&e\u5728\u5eab\u30bc\u30ed\u306e\u5168\u3066\u306e\u30b7\u30e7\u30c3\u30d7\u3092\u524a\u9664\u3057\u307e\u3059", + "find": "&e\u6307\u5b9a\u30a2\u30a4\u30c6\u30e0\u306e\u6700\u5bc4\u308a\u30b7\u30e7\u30c3\u30d7\u3092\u63a2\u3057\u307e\u3059", + "reload": "&econfig.yml \u3092\u30ea\u30ed\u30fc\u30c9\u3057\u307e\u3059", + "refill": "&e\u7279\u5b9a\u6570\u306e\u30a2\u30a4\u30c6\u30e0\u3092\u30b7\u30e7\u30c3\u30d7\u306b\u8ffd\u52a0\u3057\u307e\u3059", + "empty": "&e\u30b7\u30e7\u30c3\u30d7\u304b\u3089\u5168\u3066\u306e\u5728\u5eab\u3092\u524a\u9664\u3057\u307e\u3059", + "debug": "&e\u958b\u767a\u8005\u30e2\u30fc\u30c9\u306b\u5207\u308a\u66ff\u3048\u307e\u3059", + "create": "&e\u30bf\u30fc\u30b2\u30c3\u30c8\u3057\u305f\u30c1\u30a7\u30b9\u30c8\u306b\u65b0\u3057\u3044\u30b7\u30e7\u30c3\u30d7\u3092\u4f5c\u6210\u3057\u307e\u3059", + "fetchmessage": "&e\u672a\u8aad\u30b7\u30e7\u30c3\u30d7\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u53d6\u5f97", + "info": "&eQuickShop \u7d71\u8a08\u3092\u8868\u793a\u3057\u307e\u3059", + "paste": "&e\u30b5\u30fc\u30d0\u30fc\u30c7\u30fc\u30bf\u3092 Pastebin \u306b\u81ea\u52d5\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3057\u307e\u3059", + "staff": "&e\u30b7\u30e7\u30c3\u30d7\u30b9\u30bf\u30c3\u30d5\u3092\u7ba1\u7406\u3059\u308b", + "remove": "&e\u898b\u3066\u3044\u308b\u30b7\u30e7\u30c3\u30d7\u3092\u524a\u9664\u3057\u307e\u3059", + "amount": "&e\u91d1\u984d\u3092\u6307\u5b9a\u3057\u3066\u30a2\u30af\u30b7\u30e7\u30f3\u3092\u5b9f\u884c\u3057\u307e\u3059\uff08\u30c1\u30e3\u30c3\u30c8\u30d7\u30e9\u30b0\u30a4\u30f3\u306e\u554f\u984c\u306e\u5834\u5408\uff09", + "about": "&eQuickShop\u306e\u60c5\u5831\u3092\u8868\u793a", + "help": "&eQuickShop\u306e\u30d8\u30eb\u30d7\u3092\u8868\u793a", + "supercreate": "&e\u3059\u3079\u3066\u306e\u4fdd\u8b77\u30c1\u30a7\u30c3\u30af\u3092\u30d0\u30a4\u30d1\u30b9\u3059\u308b\u30b7\u30e7\u30c3\u30d7\u3092\u4f5c\u6210\u3059\u308b" + } + }, + "signs": { + "selling": "\u8ca9\u58f2 {0}", + "header": "&c{0}", + "buying": "\u8cb7\u53d6 {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "\u7121\u5236\u9650" + }, + "controlpanel": { + "setowner": "&a\u6240\u6709\u8005 : &b{0} &e[&d&l\u5909\u66f4&e]", + "infomation": "&a\u30b7\u30e7\u30c3\u30d7\u30b3\u30f3\u30c8\u30ed\u30fc\u30eb\u30d1\u30cd\u30eb :", + "setowner-hover": "&e\u30af\u30ea\u30c3\u30af\u3067\u6240\u6709\u8005\u5909\u66f4\u3057\u307e\u3059", + "unlimited": "&a\u7121\u5236\u9650 : {0} &e[&d&l\u5207\u66ff&e]", + "unlimited-hover": "&e\u30af\u30ea\u30c3\u30af\u3067\u5236\u9650\/\u7121\u5236\u9650\u3092\u5207\u308a\u66ff\u3048\u307e\u3059", + "mode-selling": "&a\u30b7\u30e7\u30c3\u30d7\u30e2\u30fc\u30c9 : &b\u8ca9\u58f2 &e[&d&l\u5207\u66ff&e]", + "mode-selling-hover": "&e\u30af\u30ea\u30c3\u30af\u3067\u8cb7\u53d6\u30e2\u30fc\u30c9\u306b\u5207\u308a\u66ff\u3048\u307e\u3059", + "mode-buying": "&a\u30b7\u30e7\u30c3\u30d7\u30e2\u30fc\u30c9 : &b\u8cb7\u53d6 &e[&d&l\u5207\u66ff&e]", + "mode-buying-hover": "&e\u30af\u30ea\u30c3\u30af\u3067\u8ca9\u58f2\u30e2\u30fc\u30c9\u306b\u5207\u308a\u66ff\u3048\u307e\u3059", + "price": "&a\u4fa1\u683c : &b{0} &e[&d&l\u5909\u66f4&e]", + "price-hover": "&e\u30af\u30ea\u30c3\u30af\u3067\u4fa1\u683c\u5909\u66f4\u3057\u307e\u3059", + "refill": "&aRefill : \u30b7\u30e7\u30c3\u30d7\u30a2\u30a4\u30c6\u30e0\u8ffd\u52a0 &e[&d&l\u8ffd\u52a0&e]", + "refill-hover": "&e\u30af\u30ea\u30c3\u30af\u3067\u30a2\u30a4\u30c6\u30e0\u8ffd\u52a0", + "empty": "&aEmpty : \u30b7\u30e7\u30c3\u30d7\u30a2\u30a4\u30c6\u30e0\u524a\u9664 &e[&d&l\u524a\u9664&e]", + "empty-hover": "&e\u30af\u30ea\u30c3\u30af\u3067\u30a2\u30a4\u30c6\u30e0\u524a\u9664\u3057\u307e\u3059", + "remove": "&c&l[\u30b7\u30e7\u30c3\u30d7\u524a\u9664]", + "remove-hover": "&e\u30af\u30ea\u30c3\u30af\u3067\u30b7\u30e7\u30c3\u30d7\u3092\u524a\u9664\u3057\u307e\u3059", + "commands": { + "setowner": "\/qs setowner [\u30d7\u30ec\u30a4\u30e4\u30fc\u540d]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [\u65b0\u4fa1\u683c]", + "refill": "\/qs refill [\u500b\u6570]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a\u2714", + "failed": "&c\u2718" + }, + "tabcomplete": { + "price": "[\u4fa1\u683c]", + "range": "[\u7bc4\u56f2]", + "amount": "[\u500b\u6570]" + }, + "updatenotify": { + "buttontitle": "[\u66f4\u65b0\u3059\u308b]", + "onekeybuttontitle": "[\u30ef\u30f3\u30ad\u30fc\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8]", + "list": [ + "{0} \u304c\u30ea\u30ea\u30fc\u30b9\u3055\u308c\u307e\u3057\u305f\u3002\u307e\u3060 {1} \u3092\u4f7f\u7528\u3057\u3066\u3044\u307e\u3059\uff01", + "\u65b0\u3057\u3044 {0} \u304c\u30ea\u30ea\u30fc\u30b9\u3055\u308c\u307e\u3057\u305f\u3001\u66f4\u65b0\u3057\u307e\u3057\u3087\u3046\uff01", + "\u30b5\u30d7\u30e9\u30a4\u30ba\uff01{0} \u304c\u51fa\u307e\u3057\u305f\u3002\u3042\u306a\u305f\u306f {1} \u3067\u3059", + "\u66f4\u65b0\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u3088\u3046\u3067\u3059\u3002{0} \u304c\u30ea\u30ea\u30fc\u30b9\u3055\u308c\u307e\u3057\u305f\uff01", + "\u304a\u3063\u3068\uff01 {0} \u304c\u30ea\u30ea\u30fc\u30b9\u3055\u308c\u307e\u3057\u305f\u3002\u4eca\u306f {1} \u3067\u3059\uff01", + "QuickShop\u306f {0} \u306b\u306a\u308a\u307e\u3057\u305f\u304c\u3001\u66f4\u65b0\u3055\u308c\u306a\u3044\u306e\u3067\u3059\u304b\uff1f", + "\u4fee\u6b63\u3057\u3066\u518d...\u7533\u3057\u8a33\u3042\u308a\u307e\u305b\u3093\u304c {0} \u304c\u30ea\u30ea\u30fc\u30b9\u3055\u308c\u307e\u3057\u305f\uff01", + "\u30a8\u30e9\u30fc\uff01 \u3044\u3044\u3048\u3001\u3053\u308c\u306f\u30a8\u30e9\u30fc\u3067\u306f\u306a\u304f\u3001{0} \u304c\u30ea\u30ea\u30fc\u30b9\u3055\u308c\u305f\u3070\u304b\u308a\u3067\u3059\uff01", + "\u3042\u3042\u3001\u795e\u69d8\uff01 {0} \u304c\u51fa\u307e\u3057\u305f\uff01 \u307e\u3060 {1} \u3092\u4f7f\u7528\u3057\u3066\u3044\u308b\u306e\u306f\u306a\u305c\u3067\u3059\u304b\uff1f", + "\u4eca\u65e5\u306e\u30cb\u30e5\u30fc\u30b9\uff1aQuickShop \u304c {0} \u306b\u66f4\u65b0\u3055\u308c\u307e\u3057\u305f\uff01", + "\u30d7\u30e9\u30b0\u30a4\u30f3K.I.A\u3001{0} \u306b\u66f4\u65b0\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\uff01", + "\u30d5\u30e5\u30fc\u30ba\u306f\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8 {0} \u3092\u30d5\u30e5\u30fc\u30ba\u3057\u3066\u3044\u307e\u3059\u3001\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3092\u4fdd\u5b58\u3057\u3066\u304f\u3060\u3055\u3044\uff01", + "\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u53f8\u4ee4\u5b98\u304c\u3044\u307e\u3059\u3001{0} \u304c\u767b\u5834\u3057\u307e\u3057\u305f\uff01", + "\u79c1\u306e\u30b9\u30bf\u30a4\u30eb\u3092\u898b\u3066--- {0} \u304c\u66f4\u65b0\u3055\u308c\u307e\u3057\u305f\u304c\u3001\u307e\u3060 {1} \u3092\u4f7f\u7528\u3057\u3066\u3044\u307e\u3059", + "\u3042\u3042\uff01 \u65b0\u3057\u3044\u66f4\u65b0 {0}\uff01 \u66f4\u65b0\u3092\uff01", + "\u4f55\u3092\u8003\u3048\u3066\u308b\uff1f {0} \u304c\u30ea\u30ea\u30fc\u30b9\u3055\u308c\u307e\u3057\u305f\uff01 \u66f4\u65b0\u3057\u307e\u3057\u3087\u3046\uff01" + ], + "remote-disable-warning": "&c\u3053\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u306eQuickShop\u306f\u3001\u30ea\u30e2\u30fc\u30c8\u30b5\u30fc\u30d0\u30fc\u3067\u306f\u7121\u52b9\u3068\u8a18\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u3064\u307e\u308a\u3001\u3053\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u306b\u306f\u6df1\u523b\u306a\u554f\u984c\u304c\u3042\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002SpigotMC\u30da\u30fc\u30b8\u304b\u3089\u8a73\u7d30\u3092\u53d6\u5f97\u3057\u307e\u3059\uff1a{0}\u3002\u3053\u306e\u8b66\u544a\u304c\u8868\u793a\u3055\u308c\u3001\u7121\u52b9\u306b\u306a\u3063\u3066\u3044\u306a\u3044\u4ed6\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u4f7f\u7528\u3057\u3066\u3053\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u7f6e\u304d\u63db\u3048\u308b\u307e\u3067\u3001\u30b3\u30f3\u30bd\u30fc\u30eb\u306b\u8868\u793a\u304c\u7d9a\u304d\u307e\u3059\u3002\u30b5\u30fc\u30d0\u30fc\u306e\u5b9f\u884c\u306b\u306f\u5f71\u97ff\u3057\u307e\u305b\u3093\u3002", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&c{0}\u306e\u30b7\u30e7\u30c3\u30d7\u306f\u5341\u5206\u306a\u8cc7\u91d1\u304c\u306a\u304b\u3063\u305f\u305f\u3081\u524a\u9664\u3055\u308c\u307e\u3057\u305f", + "digits-reach-the-limit": "&c\u4fa1\u683c\u306e\u5c0f\u6570\u70b9\u4ee5\u4e0b\u306e\u5236\u9650\u306b\u9054\u3057\u307e\u3057\u305f\u3002", + "complete": "&a\u5b8c\u4e86!" +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/ko.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/ko.json new file mode 100644 index 0000000..4455c98 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/ko.json @@ -0,0 +1,234 @@ +{ + "translation-author": "Encode : UTF-8\n\ubc88\uc5ed\uc790 : WaterFrost,FLASH,ruddls030", + "translation-version": "\uc9c0\uc6d0 \ubc84\uc804: Reremake", + "translation-contributors": "\uae30\uc5ec\uc790: Timtower, Netherfoam, KaiNoMood, Mgazul", + "translation-country": "\uc5b8\uc5b4 \uc9c0\uc5ed: \ud55c\uad6d\uc5b4 (Ko)", + "language-version": "27", + "not-looking-at-shop": "&c\ud035\uc0f5\uc744 \ucc3e\uc744\uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \ub2f9\uc2e0\uc740 \ubc18\ub4dc\uc2dc \uc0c1\uc810\uc744 \ubcf4\uace0\uc788\uc5b4\uc57c \ud569\ub2c8\ub2e4.", + "no-anythings-in-your-hand": "&c\ub2f9\uc2e0\uc758 \uc190\uc5d0 \uc544\ubb34\uac83\ub3c4 \uc5c6\uc2b5\ub2c8\ub2e4.", + "no-permission": "&c\ub2f9\uc2e0\uc5d0\uac8c\ub294 \uad8c\ud55c\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.", + "no-creative-break": "&c\ub2f9\uc2e0\uc740 \ud06c\ub9ac\uc5d0\uc774\ud2f0\ube0c \ubaa8\ub4dc\uc77c \ub54c \ub2e4\ub978\uc0ac\ub78c\uc758 \uc0c1\uc810\uc744 \ubd80\uc220 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \uc11c\ubc14\uc774\ubc8c \ubaa8\ub4dc\ub85c \ubc14\uafb8\uc2ed\uc2dc\uc624.", + "no-double-chests": "&c\ub2f9\uc2e0\uc740 DoubleChest \uc0c1\uc810\uc744 \ub9cc\ub4e4 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.", + "shop-already-owned": "&c\uc0c1\uc810\uc774 \uc774\ubbf8 \uc788\uc2b5\ub2c8\ub2e4.", + "chest-was-removed": "&c\uc0c1\uc790\ub294 \uc81c\uac70\ub418\uc5c8\uc2b5\ub2c8\ub2e4.", + "price-too-cheap": "&c\uac00\uaca9\uc740 \ubc18\ub4dc\uc2dc &e${0} &c\ubcf4\ub2e4 \ub192\uc544\uc57c\ud569\ub2c8\ub2e4.", + "no-price-change": "&c\uac00\uaca9\uc744 \ubcc0\uacbd\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4!", + "you-cant-afford-a-new-shop": "&c\uc0c8 \uc0c1\uc810 \uc0dd\uc131\uc5d0 {0} \uc6d0\uc774 \uc18c\ubaa8\ub429\ub2c8\ub2e4!", + "player-bought-from-your-store-tax": "&c{0}\ub2d8\uc774 \uc720\uc800\ub2d8\uc758 \uc0c1\uc810 \uc5d0\uc11c {1} {2}\uc744(\ub97c) \uad6c\uc785\ud588\uc73c\uba70 \uc138\uae08\uc73c\ub85c {3}\uc6d0 \uc744(\ub97c) \uc9c0\ubd88\ud558\uc168\uc2b5\ub2c8\ub2e4!", + "you-cant-afford-to-change-price": "&c\uc0c1\uc810 \uac00\uaca9\uc744 \ubcc0\uacbd\ud558\ub294 \ub370 {0}\uc6d0\uc774 \uc18c\ubaa8\ub429\ub2c8\ub2e4!", + "success-created-shop": "&c\uc0c1\uc810\uc744 \ub9cc\ub4e4\uc5c8\uc2b5\ub2c8\ub2e4.", + "success-removed-shop": "&c\uc0c1\uc810\uc744 \uc81c\uac70\ud588\uc2b5\ub2c8\ub2e4.", + "shops-arent-locked": "&c\uae30\uc5b5\ud558\uc138\uc694, \uc0c1\uc810\ub294 \ub3c4\ub09c\uc73c\ub85c\ubd80\ud130 \ubcf4\ud638\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4! \ub3c4\ub09c\uc744 \ub9c9\uc73c\ub824\uba74 LWC, Lockette \ub4f1\uc73c\ub85c \uc7a0\uad6c\uc138\uc694!", + "shop-creation-cancelled": "&c\uc0c1\uc810 \uac1c\uc124\uc744 \ucde8\uc18c\ud588\uc2b5\ub2c8\ub2e4.", + "shop-purchase-cancelled": "&c\uad6c\ub9e4\ub97c \ucde8\uc18c\ud588\uc2b5\ub2c8\ub2e4.", + "shop-stock-too-low": "&c\uc0c1\uc810\uc5d0\ub294 {0} {1} \uac1c\uc758 \uc0c1\ud488\uc774 \ub0a8\uc544 \uc788\uc2b5\ub2c8\ub2e4.", + "you-cant-afford-to-buy": "&c\ube44\uc6a9\uc740 {0}\uc774\uc9c0\ub9cc, \ub2f9\uc2e0\uc740 {1}\ub9cc \uac00\uc9c0\uace0 \uc788\uc2b5\ub2c8\ub2e4.", + "negative-amount": "&c\uba4d\uccad\uc774! \uc74c\uc218\ub85c \uac00\uaca9\uc744 \uc815\ud560 \uc218\ub294 \uc5c6\uc2b5\ub2c8\ub2e4.", + "not-a-number": "&c\uc22b\uc790\ub9cc \uc785\ub825\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4\ub9cc, \ub2f9\uc2e0\uc740 {0}\uc744 \uc785\ub825\ud588\uc2b5\ub2c8\ub2e4.", + "not-a-integer": "&c\uc815\uc218\ub9cc \uc785\ub825\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4\ub9cc, \ub2f9\uc2e0\uc740 {0}\uc744 \uc785\ub825\ud588\uc2b5\ub2c8\ub2e4.", + "player-bought-from-your-store": "&c{0}\ub2d8\uc774 \uc720\uc800\ub2d8\uc758 \uc0c1\uc810\uc5d0\uc11c {1} {2}\uc744 (\ub97c) \uad6c\ub9e4\ud588\uc2b5\ub2c8\ub2e4.", + "shop-out-of-stock": "&5{0}, {1}, {2}\uc5d0 \uc788\ub294 \uc720\uc800\ub2d8\uc758 \uac00\uac8c\uc5d0 {3}\uc774 (\uac00) \ubd80\uc871\ud569\ub2c8\ub2e4.", + "shop-has-no-space": "&c\uac00\uac8c\uc5d0\ub294 {0} \uc774\uc0c1\uc758 {1}\uc758 \uacf5\uac04 \ub9cc \uc788\uc2b5\ub2c8\ub2e4.", + "you-dont-have-that-many-items": "&c\uc720\uc800\ub2d8\uc740 {0} {1} \ubc16\uc5d0 \uc5c6\uc2b5\ub2c8\ub2e4.", + "the-owner-cant-afford-to-buy-from-you": "&c\ube44\uc6a9\uc740 {0}\uc774\uc9c0\ub9cc, \ub2f9\uc2e0\uc740 {1}\ub9cc \uac00\uc9c0\uace0 \uc788\uc2b5\ub2c8\ub2e4.", + "player-sold-to-your-store": "&a{0}\ub2d8\uc774 {1} {2}\uc744 (\ub97c) \uc720\uc800\ub2d8\uc758 \uc0c1\uc810\uc5d0 \ud310\ub9e4\ud588\uc2b5\ub2c8\ub2e4.", + "shop-out-of-space": "&5\uc720\uc800\ub2d8\uc758 {0}, {1}, {2}\uc5d0 \uc788\ub294 \uc0c1\uc810\uc774 \uac00\ub4dd \ucc3c\uc2b5\ub2c8\ub2e4.", + "fee-charged-for-price-change": "&a\uac00\uaca9\uc744 \ubcc0\uacbd\ud558\ub824\uba74 &c{0}&a\uc6d0\uc744 \uc9c0\ubd88\ud574\uc57c\ud569\ub2c8\ub2e4.", + "price-is-now": "&a\uc0c1\uc810\uc758 \uc0c8\ub85c\uc6b4 \uac00\uaca9\uc740 &e{0}\uc6d0 \uc785\ub2c8\ub2e4.", + "thats-not-a-number": "&c\uc798\ubabb\ub41c \uc22b\uc790\uc785\ub2c8\ub2e4. \ud655\uc778\ud558\uc2dc\uace0 \ub2e4\uc2dc \uc785\ub825\ud558\uc138\uc694.", + "no-price-given": "&c\uc720\ud6a8\ud55c \uac00\uaca9\uc744 \uc8fc\uc138\uc694.", + "average-price-nearby": "&a\uc778\uadfc \ud3c9\uade0 \uac00\uaca9: &e{0}\uc6d0", + "shop-has-changed": "&c\uc720\uc800\ub2d8\uc774 \uc0ac\uc6a9\ud558\ub824\uace0 \ud588\ub358 \uc0c1\uc810\uc774 \uc720\uc800\ub2d8\uc774 \ud074\ub9ad\ud55c \uc774\ud6c4\ub85c \ubcc0\uacbd\ub418\uc5c8\uc2b5\ub2c8\ub2e4!", + "shop-not-exist": "&c\uc0c1\uc810\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.", + "nearby-shop-this-way": "&a\uc0c1\uc810\uc740 \ub2f9\uc2e0\uc744 \uae30\uc900\uc73c\ub85c {0}\ube14\ub85d \ub5a8\uc5b4\uc9c4 \uacf3\uc5d0 \uc788\uc2b5\ub2c8\ub2e4.", + "no-nearby-shop": "&c\uadfc\ucc98\uc5d0 {0}\uc744(\ub97c) \ud30c\ub294 \uc77c\uce58\ud558\ub294 \uc0c1\uc810\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.", + "buying-more-than-selling": "&c\uc8fc\uc758 : \ub2f9\uc2e0\uc774 \uad6c\ub9e4\ud558\ub824\ub294 \uc218\ub7c9\uc774 \ud310\ub9e4\ud558\ub294 \uc218\ub7c9\ubcf4\ub2e4 \ub9ce\uc2b5\ub2c8\ub2e4!", + "not-enough-space": "&c\uc774 \uc911 {0}\uac1c\ub97c \ub354 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \uacf5\uac04\ub9cc \uc788\uc2b5\ub2c8\ub2e4!", + "refill-success": "&a\uc131\uacf5\uc801\uc73c\ub85c \ucc44\uc6e0\uc2b5\ub2c8\ub2e4.", + "empty-success": "&a\uc131\uacf5\uc801\uc73c\ub85c \ube44\uc6e0\uc2b5\ub2c8\ub2e4.", + "admin-shop": "\uad00\ub9ac\uc790 \uc0c1\uc810", + "unknown-owner": "\uc54c \uc218 \uc5c6\ub294 \uc8fc\uc778", + "owner-bypass-check": "&e\ubaa8\ub4e0 \uc870\uc0ac\ub97c \ud1b5\uacfc\ud558\uc5ec, \uac70\ub798\ub97c \uc644\ub8cc\ud588\uc2b5\ub2c8\ub2e4! (\ub2f9\uc2e0\uc740 \uc0c1\uc810 \uc8fc\uc778\uc785\ub2c8\ub2e4.)", + "reached-maximum-can-create": "&c\ub2f9\uc2e0\uc740 \uc774\ubbf8 \ucd5c\ub300 {0}\/{1}\uac1c\uc758 \uc0c1\uc810\uc744 \uc0dd\uc131\ud588\uc2b5\ub2c8\ub2e4!", + "restricted-prices": "&c{0}\uc5d0 \ub300\ud55c \uac00\uaca9\uc774 \uc81c\ud55c\ub418\uc5c8\uc2b5\ub2c8\ub2e4. \ucd5c\uc18c {1}\uc6d0, \ucd5c\ub300 {2}\uc6d0", + "no-enough-money-to-keep-shops": "&c\ub2f9\uc2e0\uc740 \ub2f9\uc2e0\uc758 \uc0c1\uc810\uc720\uc9c0\uc5d0 \ucda9\ubd84\ud55c \ub3c8\uc774 \uc5c6\uc2b5\ub2c8\ub2e4! \ubaa8\ub4e0\uc0c1\uc810\uc774 \uc81c\uac70 \ub429\ub2c8\ub2e4...", + "nothing-to-flush": "&a\uc0c8\ub85c\uc6b4 \uc0c1\uc810 \uba54\uc138\uc9c0\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.", + "break-shop-use-supertool": "&e \ub2f9\uc2e0\uc740 SuperTool\uc744 \uc774\uc6a9\ud574 \uc0c1\uc810\uc744 \ud30c\uad34\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.", + "failed-to-put-sign": "&c\uc0c1\uc810\uc815\ubcf4 \ud33b\ub9d0\uc744 \uc124\uce58\ud558\uae30 \uc704\ud55c \ucda9\ubd84\ud55c \uacf5\uac04\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.", + "failed-to-paste": "&cPastebin\uc5d0 \ub370\uc774\ud130 \uc5c5\ub85c\ub4dc\uc5d0 \uc2e4\ud328\ud588\uc2b5\ub2c8\ub2e4. \uc778\ud130\ub137\uc744 \ud655\uc778\ud55c \ud6c4 \ub2e4\uc2dc \uc2dc\ub3c4\ud558\uc2ed\uc2dc\uc624. (\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 \ucf58\uc194\uc744 \ucc38\uc870\ud558\uc138\uc694.)", + "warn-to-paste": "&e\ub370\uc774\ud130\ub97c \uc218\uc9d1\ud558\uace0 Pastebin\uc5d0 \uc5c5\ub85c\ub4dc\ud558\ub294 \ub370 \uc2dc\uac04\uc774 \uac78\ub9b4 \uc218 \uc788\uc2b5\ub2c8\ub2e4. &c&l\uc8fc\uc758!&c. \ub370\uc774\ud130\ub294 \uc77c\uc8fc\uc77c \ub3d9\uc548 \uacf5\uac1c\ub418\uba70 \uc11c\ubc84 \uad6c\uc131\uc774 \uc720\ucd9c\ub420 \uc218 \uc788\uc73c\ubbc0\ub85c \uc2e0\ub8b0\ud560 \uc218 \uc788\ub294 \uc9c1\uc6d0\/\uac1c\ubc1c\uc790\uc5d0\uac8c\ub9cc \uc804\uc1a1\ud574\uc57c \ud569\ub2c8\ub2e4.", + "price-too-high": "&c\uc0c1\uc810\uc758 \uac00\uaca9\uc774 \ub108\ubb34 \ub192\uc2b5\ub2c8\ub2e4! \ub2f9\uc2e0\uc740 {0}\uc6d0 \uc774\uc0c1\uc758 \uc0c1\uc810\uc744 \ub9cc\ub4e4\uc218 \uc5c6\uc2b5\ub2c8\ub2e4!", + "you-cant-create-shop-in-there": "&c\ub2f9\uc2e0\uc740 \uc774 \uc704\uce58\uc5d0 \uc0c1\uc810\uc744 \uc124\uce58\ud560 \uc218 \uc788\ub294 \uad8c\ud55c\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.", + "unknown-player": "&c\ub300\uc0c1 \ud50c\ub808\uc774\uc5b4\uac00 \uc5c6\uc2b5\ub2c8\ub2e4. \uc720\uc800\uc774\ub984\uc744 \ud655\uc778\ud574\uc8fc\uc138\uc694.", + "shop-staff-cleared": "&a\uc131\uacf5\uc801\uc73c\ub85c \ub2f9\uc2e0 \uc0c1\uc810\uc758 \ubaa8\ub4e0 \uad00\ub9ac\uc790\ub97c \ud574\uace0\ud558\uc600\uc2b5\ub2c8\ub2e4.", + "shop-staff-added": "&a\uc131\uacf5\uc801\uc73c\ub85c {0}\ub2d8\uc744 \ub2f9\uc2e0\uc758 \uc0c1\uc810\uc5d0 \uace0\uc6a9\ud558\uc600\uc2b5\ub2c8\ub2e4.", + "shop-staff-deleted": "&a\uc131\uacf5\uc801\uc73c\ub85c {0}\ub2d8\uc744 \ub2f9\uc2e0\uc758 \uc0c1\uc810\uc5d0\uc11c \ud574\uace0\ud558\uc600\uc2b5\ub2c8\ub2e4.", + "no-permission-build": "&c\ub2f9\uc2e0\uc740 \uc774 \uc704\uce58\uc5d0 \uc0c1\uc810\uc744 \ub9cc\ub4e4 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.", + "success-change-owner-to-server": "&a\uc131\uacf5\uc801\uc73c\ub85c \uc0c1\uc810 \uc18c\uc720\uc790\ub97c \uc11c\ubc84\ub85c \uc124\uc815\ud588\uc2b5\ub2c8\ub2e4.", + "flush-finished": "&a\uc131\uacf5\uc801\uc73c\ub85c \uac70\ub798 \uae30\ub85d\uc744 \uc81c\uac70\ud558\uc600\uc2b5\ub2c8\ub2e4.", + "purchase-failed": "&c\uad6c\ub9e4 \uc2e4\ud328: \ub0b4\ubd80 \uc624\ub958. \uc11c\ubc84\uc758 \uad00\ub9ac\uc790\uc5d0\uac8c \ubb38\uc758\ud558\uc138\uc694", + "no-pending-action": "&c\ucc98\ub9ac \ub300\uae30\uc911\uc778 \ub0b4\uc5ed\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.", + "permission-denied-3rd-party": "&c\uc561\uc138\uc2a4\uac00 \uac70\ubd80\ub418\uc5c8\uc2b5\ub2c8\ub2e4: \uc81c\uc0bc\uc790 \ud50c\ub7ec\uadf8\uc778 [{0}].", + "menu": { + "successful-purchase": "&a\uc131\uacf5\uc801\uc73c\ub85c \uad6c\ub9e4\ud588\uc2b5\ub2c8\ub2e4:", + "successfully-sold": "&a\uc131\uacf5\uc801\uc73c\ub85c \ud310\ub9e4\ud588\uc2b5\ub2c8\ub2e4:", + "item-name-and-price": "&e{0}\uac1c&a\uc758 &e{1} &a(\ucd1d &e{2}&a)", + "sell-tax": "&a\ub2f9\uc2e0\uc740 \uc138\uae08\uc73c\ub85c &e{0}\uc6d0&a\uc744 \uc9c0\ubd88\ud588\uc2b5\ub2c8\ub2e4.", + "sell-tax-self": "&a\ub2f9\uc2e0\uc740 \uc774 \uc0c1\uc810\uc758 \uc8fc\uc778 \uc774\ubbc0\ub85c \uc138\uae08\uc774 \uc81c\uc678\ub429\ub2c8\ub2e4.", + "enchants": "&5\ubd80\uc5ec\ub41c \ub9c8\ubc95", + "stored-enchants": "&5\ubd80\uc5ec \uac00\ub2a5\ud55c \ub9c8\ubc95", + "shop-information": "&a\uc0c1\uc810 \uc815\ubcf4 :", + "owner": "&a\uc8fc\uc778 : {0}", + "item": "&a\uc544\uc774\ud15c : &e{0}", + "preview": "&b[\uc544\uc774\ud15c \ubbf8\ub9ac\ubcf4\uae30]", + "space": "&a\ube48 \uacf5\uac04 : &e{0}", + "stock": "&a\uc7ac\uace0\ud488 &e{0}", + "price-per": "&e{0}&a\uc758 \uac1c\ub2f9 \uac00\uaca9 &a- &e{1}", + "total-value-of-chest": "&a\uc0c1\uc790\uc758 \ucd1d \uac00\uce58 : &e{0}\uc6d0", + "damage-percent-remaining": "&a\ub0a8\uc740 \ub0b4\uad6c\ub3c4 : &e{0}%", + "this-shop-is-buying": "&a\uc774 \uc0c1\uc810\uc740 \uc544\uc774\ud15c\uc744 &d\uad6c\ub9e4&a\uc911\uc778 \uc0c1\uc810\uc785\ub2c8\ub2e4.", + "this-shop-is-selling": "&a\uc774 \uc0c1\uc810\uc740 \uc544\uc774\ud15c\uc744 &d\ud310\ub9e4&a\uc911\uc778 \uc0c1\uc810\uc785\ub2c8\ub2e4.", + "effects": "&a\ud6a8\uacfc", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&a QuickShop \uc7a0\uae08 \ubb34\uc2dc!", + "that-is-locked": "&c\uc774 \uc0c1\uc810\uc740 \uc7a0\uacbc\uc2b5\ub2c8\ub2e4.", + "how-many-buy": "&a\ucc44\ud305\uc73c\ub85c \uc6d0\ud558\ub294 &b\uad6c\ub9e4&a \uac1c\uc218\ub97c \uc785\ub825\ud574\uc8fc\uc138\uc694. \ub2f9\uc2e0\uc740 &e{0}&a\uac1c\ub97c \uad6c\ub9e4\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. &ball&a\uc744 \uc785\ub825\ud574 \uc804\ubd80 \uad6c\ub9e4 \uac00\ub2a5.", + "how-many-sell": "&a\ucc44\ud305\uc73c\ub85c \uc6d0\ud558\ub294 &b\ud310\ub9e4&a \uac1c\uc218\ub97c \uc785\ub825\ud574\uc8fc\uc138\uc694. \ub2f9\uc2e0\uc740 &e{0}&a\uac1c\ub97c \ud310\ub9e4\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. &ball&a\uc744 \uc785\ub825\ud574 \uc804\ubd80 \ud310\ub9e4 \uac00\ub2a5.", + "not-allowed-to-create": "&c \ub2f9\uc2e0\uc740 \uc774\uacf3\uc5d0 \uc0c1\uc810\uc744 \ub9cc\ub4e4\uc218 \uc5c6\uc2b5\ub2c8\ub2e4.", + "blacklisted-item": "&c\uc774 \uc544\uc774\ud15c\uc740 \uae08\uc9c0\ub41c \uc544\uc774\ud15c\uc785\ub2c8\ub2e4. \ub2f9\uc2e0\uc740 \uc774 \uc544\uc774\ud15c\uc744 \ud310\ub9e4\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.", + "how-much-to-trade-for": "&a\ucc44\ud305\uc5d0 &e{0}&a\uc640 \uad50\ud658\ud560 \uae08\uc561\uc744 \uc785\ub825\ud574\uc8fc\uc138\uc694.", + "command": { + "toggle-unlimited": { + "unlimited": "&\uc0c1\uc810\uc758 \uc7ac\uace0\uac00 \ubb34\uc81c\ud55c\uc774 \ub418\uc5c8\uc2b5\ub2c8\ub2e4.", + "limited": "&a\uc0c1\uc810\uc758 \uc7ac\uace0\uac00 \ud55c\uc815\ub418\uc5c8\uc2b5\ub2c8\ub2e4." + }, + "no-owner-given": "&c\uc8fc\uc778\uc774 \uc5c6\uc2b5\ub2c8\ub2e4. &a\/qs setowner <\ud50c\ub808\uc774\uc5b4 \uc774\ub984>&c\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc8fc\uc778\uc744 \uc9c0\uc815\ud558\uc138\uc694.", + "new-owner": "&a\uc0c8 \uc8fc\uc778 : &e{0}", + "now-buying": "&a\uc774\uc81c &e{0}&a\ub97c \uad6c\ub9e4\ud569\ub2c8\ub2e4.", + "now-selling": "&a\uc774\uc81c &e{0}&a\ub97c \ud310\ub9e4\ud569\ub2c8\ub2e4.", + "cleaning": "&a\uc7ac\uace0\uac00 0\uac1c\uc778 \uc0c1\uc810 \uc815\ub9ac\uc911....", + "reloading": "&a\ub9ac\ub85c\ub4dc \uc911...", + "cleaned": "&e{0}\uac1c&a\uc758 \uc0c1\uc810\uc744 \uc815\ub9ac\ud588\uc2b5\ub2c8\ub2e4", + "no-type-given": "&c\uc0ac\uc6a9\ubc95: \/qs find <\uc544\uc774\ud15c \uc774\ub984>", + "no-amount-given": "&a<\uac1c\uc218>&c\uac00 \uc8fc\uc5b4\uc9c0\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4. &a\/qs refill <\uac1c\uc218>&c\ub97c \uc0ac\uc6a9\ud558\uc5ec \ubb3c\ud488\uc744 \ubcf4\ucda9\ud558\uc138\uc694.", + "now-debuging": "&a\uac1c\ubc1c\uc790 \ubaa8\ub4dc\ub85c \ubcc0\uacbd \uc644\ub8cc. Quickshop \ub9ac\ub85c\ub4dc \uc911...", + "now-nolonger-debuging": "&a\uc77c\ubc18 \ubaa8\ub4dc\ub85c \ubcc0\uacbd \uc644\ub8cc. Quickshop \ub9ac\ub85c\ub4dc \uc911...", + "wrong-args": "&c\ub9de\ub294 \uba85\ub839\uc5b4\uac00 \uc544\ub2d9\ub2c8\ub2e4. \/qs help \ub97c \uc0ac\uc6a9\ud558\uc5ec \ub3c4\uc6c0\ub9d0\uc744 \ud655\uc778\ud558\uc138\uc694", + "description": { + "title": "&aQuickshop \ub3c4\uc6c0\ub9d0", + "unlimited": "&e\uc0c1\uc810 \uc7ac\uace0\ub97c \ubb34\uc81c\ud55c\uc73c\ub85c \ub9cc\ub4ed\ub2c8\ub2e4.", + "setowner": "&e\uc0c1\uc810 \uc18c\uc720\uc790\ub97c \ubcc0\uacbd\ud569\ub2c8\ub2e4.", + "owner": "&e\uc0c1\uc810 \uc18c\uc720\uc790\ub97c \ubcc0\uacbd\ud569\ub2c8\ub2e4.", + "buy": "&e\uc0c1\uc810\uc744 &d\uad6c\ub9e4&e\ub85c \uc804\ud658\ud558\uc600\uc2b5\ub2c8\ub2e4.", + "sell": "&e\uc0c1\uc810\uc744 &b\ud310\ub9e4&e\ub85c \uc804\ud658\ud558\uc600\uc2b5\ub2c8\ub2e4.", + "price": "&e\uc0c1\uc810\uc758 \uad6c\ub9e4\/\ud310\ub9e4 \uac00\uaca9\uc744 \ubcc0\uacbd\ud569\ub2c8\ub2e4.", + "clean": "&e\uc7ac\uace0\uac00 0\uc778 \ubaa8\ub4e0 \uc0c1\uc810\uc744 \uc81c\uac70\ud569\ub2c8\ub2e4", + "find": "&e\ud2b9\uc815 \uc720\ud615\uc758 \uac00\uc7a5 \uac00\uae4c\uc6b4 \uc0c1\uc810\uc744 \ucc3e\uc2b5\ub2c8\ub2e4.", + "reload": "&eQuickshop\uc758 config.yml \ud30c\uc77c\uc744 \ub2e4\uc2dc \ubd88\ub7ec\uc635\ub2c8\ub2e4.", + "refill": "&e\uc0c1\uc810\uc758 \uc544\uc774\ud15c\uc744 \uc785\ub825\ud55c \uc22b\uc790\ub9cc\ud07c \ucc44\uc6c1\ub2c8\ub2e4.", + "empty": "&e\uc0c1\uc810\uc758 \ubaa8\ub4e0 \uc7ac\uace0\ub97c \uc81c\uac70\ud569\ub2c8\ub2e4.", + "debug": "&e\uac1c\ubc1c\uc790 \ubaa8\ub4dc\ub85c \ubcc0\uacbd\ud569\ub2c8\ub2e4.", + "create": "&e\ubc14\ub77c\ubcf4\ub294 \uc0c1\uc790\uc5d0 \uc0c8 \uc0c1\uc810\uc744 \ub9cc\ub4ed\ub2c8\ub2e4.", + "fetchmessage": "&e\uc77d\uc9c0 \uc54a\uc740 \uc0c1\uc810 \uba54\uc2dc\uc9c0\ub97c \uac00\uc838\uc635\ub2c8\ub2e4.", + "info": "&eQuickShop\uc758 \ud1b5\uacc4\ub97c \ud45c\uc2dc\ud569\ub2c8\ub2e4", + "paste": "&e\uc11c\ubc84 \ub370\uc774\ud130\ub97c Pastebin\uc5d0 \uc790\ub3d9 \uc5c5\ub85c\ub4dc\ud569\ub2c8\ub2e4.", + "staff": "&e\ub2f9\uc2e0\uc758 \uc0c1\uc810 \uad00\ub9ac\uc790\ub97c \uad00\ub9ac\ud569\ub2c8\ub2e4.", + "remove": "&e\ubc14\ub77c\ubcf4\uace0 \uc788\ub294 \uc0c1\uc810\uc744 \uc81c\uac70\ud569\ub2c8\ub2e4.", + "amount": "&e\uac70\ub798 \uc22b\uc790 \uc785\ub825\uc744 \uba85\ub839\uc5b4\ub85c \uc2dc\ud589\ud569\ub2c8\ub2e4(\ucc44\ud305 \ud50c\ub7ec\uadf8\uc778 \ucda9\ub3cc \ubb38\uc81c)", + "about": "&eQuickShop \ud50c\ub7ec\uadf8\uc778\uc758 \uc815\ubcf4\ub97c \ubd05\ub2c8\ub2e4.", + "help": "&eQuickShop \uba85\ub839\uc5b4 \ubaa9\ub85d\uc744 \ubd05\ub2c8\ub2e4.", + "supercreate": "&e\ubaa8\ub4e0 \ubcf4\ud638\ub97c \uc6b0\ud68c\ud558\uace0 \uc0c1\uc810\uc744 \uac1c\uc124\ud569\ub2c8\ub2e4." + } + }, + "signs": { + "selling": "\ud310\ub9e4 {0}", + "header": "&c{0}", + "buying": "\uad6c\ub9e4 {0}", + "item": "{0}", + "price": "\uac1c\ub2f9 {0}", + "unlimited": "\ubb34\uc81c\ud55c" + }, + "controlpanel": { + "setowner": "&a\uc8fc\uc778: &b{0} &e[d&l\ubc14\uafb8\uae30&e]", + "infomation": "&a\uc0c1\uc810 \uc81c\uc5b4\ud310:", + "setowner-hover": "&e\ub20c\ub7ec\uc11c \uc8fc\uc778 \ubcc0\uacbd", + "unlimited": "&a\ubb34\uc81c\ud55c:{0} &e[&d&l\ubcc0\uacbd&e]", + "unlimited-hover": "&e\uc0c1\uc810 \uc7ac\uace0\uac00 \ubb34\uc81c\ud55c\uc77c \uacbd\uc6b0 \ub20c\ub7ec\uc11c \uc804\ud658", + "mode-selling": "&a\uc0c1\uc810 \ubaa8\ub4dc: &b\ud310\ub9e4\uc911 &e[&d&l\ubcc0\uacbd&e]", + "mode-selling-hover": "&e\ub20c\ub7ec\uc11c \uad6c\ub9e4\ubaa8\ub4dc\ub85c \uc804\ud658", + "mode-buying": "&a\uc0c1\uc810 \ubaa8\ub4dc: &b\uad6c\ub9e4\uc911 &e[&d&l\ubcc0\uacbd&e]", + "mode-buying-hover": "&e\ub20c\ub7ec\uc11c \ud310\ub9e4\ubaa8\ub4dc\ub85c \uc804\ud658", + "price": "&a\uac00\uaca9: &b{0} &e[&d&l\uc124\uc815&e]", + "price-hover": "&e\ub20c\ub7ec\uc11c \uc0c8\ub85c\uc6b4 \uac00\uaca9 \uc124\uc815", + "refill": "&a\ucc44\uc6b0\uae30: \uc0c1\uc810\uc758 \uc544\uc774\ud15c\uc744 \ucc44\uc6b0\uc2dc\uaca0\uc2b5\ub2c8\uae4c? &e[&d&l\ub124&e]", + "refill-hover": "&e\ub20c\ub7ec\uc11c \ucc44\uc6b0\uae30", + "empty": "&a\uc81c\uac70 : \uc0c1\uc810\uc758 \ubaa8\ub4e0 \uc544\uc774\ud15c\uc744 \uc81c\uac70\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c? &e[&d&l\ub124&e]", + "empty-hover": "&e\ub20c\ub7ec\uc11c \uc0c1\uc810 \ube44\uc6b0\uae30", + "remove": "&c&l[\uc0c1\uc810 \uc81c\uac70]", + "remove-hover": "&e \ud074\ub9ad\ud574\uc11c \uc0c1\uc810 \uc0ad\uc81c.", + "commands": { + "setowner": "\/qs setowner [\ud50c\ub808\uc774\uc5b4]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [\uc0c8 \uac00\uaca9]", + "refill": "\/qs refill [\uc218\ub7c9]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a\u2714", + "failed": "&c\u2718" + }, + "tabcomplete": { + "price": "[\uac00\uaca9]", + "range": "[\ubc94\uc704]", + "amount": "[\uc218\ub7c9]" + }, + "updatenotify": { + "buttontitle": "[\uc9c0\uae08 \uc5c5\ub370\uc774\ud2b8]", + "onekeybuttontitle": "[\uc989\uc2dc \uc5c5\ub370\uc774\ud2b8]", + "list": [ + "{0}\uc774\/\uac00 \ucd9c\uc2dc\ub418\uc5c8\uc2b5\ub2c8\ub2e4, \ud604\uc7ac {1}\uc744\/\ub97c \uc0ac\uc6a9\uc911\uc785\ub2c8\ub2e4.", + "\uc9e0! {0} \ucd9c\uc2dc! \uc5c5\ub370\uc774\ud2b8\ud558\uc138\uc694!", + "\uc9dc\uc794! {0} \ucd9c\uc2dc! \ub2f9\uc2e0\uc740 \uc544\uc9c1 {1}", + "\ubcf4\uc544\ud558\ub2c8 \ub2f9\uc2e0\uc740 \uc5c5\ub370\uc774\ud2b8\uac00 \ud544\uc694\ud55c \uac83\ucc98\ub7fc \ubcf4\uc774\ub124\uc694 {0}\uac00 \uacf5\uac1c\ub410\uc5b4\uc694!", + "\uc800\ub7f0! {0} \uac00 \uacf5\uac1c\ub410\uc5b4\uc694! \ub2f9\uc2e0\uc740 {1} \uc778\ub370!", + "\ub0b4\uac00 \uc57d\uc18d\ud558\ub294\ub370 \ud035\uc0f5\uc740 {0} \uc73c\ub85c \uc5c5\ub370\uc774\ud2b8 \ub418\uc5c8\uc2b5\ub2c8\ub2e4 \uc65c \uc5c5\ub370\uc774\ud2b8 \uc548\ud574\uc694?", + "\uc218\uc815 \ud6c4 \uc7ac\ub85c\u3137... \uc8c4\uc1a1\ud569\ub2c8\ub2e4 {0}\uc774 \ucd9c\uc2dc\ud588\uc2b5\ub2c8\ub2e4!", + "\uc5d0\ub7ec! \uac00 \uc544\ub2c8\ub77c {0} \uc774\uc81c \ucd9c\uc2dc!", + "\uc138\uc0c1\uc5d0! {0}\uac00 \ucd9c\uc2dc\ub410\uc5b4\uc694! \uc65c \uc544\uc9c1\ub3c4 {1}\uc744 \uc0ac\uc6a9\ud558\uc8e0?", + "\uc624\ub298\uc758 \ub274\uc2a4: \ud035\uc0f5\uc774 {0} \uc73c\ub85c \uc5c5\ub370\uc774\ud2b8 \ub418\uc5c8\uc2b5\ub2c8\ub2e4!", + "\ud50c\ub7ec\uadf8\uc778 \uc0ac\ub9dd.. \ub2f9\uc2e0\uc740 {0}\uc73c\ub85c \uc5c5\ub370\uc774\ud2b8 \ud574\uc57c\ud574\uc694!", + "{0}\uc774 \ub098\uc654\ub294\ub370 \uc5c5\ub370\uc774\ud2b8 \ud560\uaebc\uc57c \uc548\ud560\uaebc\uc57c!", + "\uc5c5\ub370\uc774\ud2b8\uac00 \uc788\uc2b5\ub2c8\ub2e4, \uc0ac\ub839\uad00\ub2d8! {0} \uc774 \ucd9c\uc2dc\ud588\uc2b5\ub2c8\ub2e4!", + "\ub0b4 \uc2a4\ud0c0\uc77c\uc880 \ubd10! {0} \uc5c5\ub370\uc774\ud2b8! \ub10c \uc544\uc9c1 {1}\uc744 \uc4f0\ub294\uc911!", + "\u314b\u314b\u314b\u314b\u314b\u314b\u314b\u314b \uc0c8\ub85c\uc6b4 {0} \uc5c5\ub370\uc774\ud2b8!", + "\ubb34\uc2a8 \uc0dd\uac01\uc774\uc138\uc694? {0} \ubc84\uc804\uc774 \ucd9c\uc2dc\ub410\ub294\ub370! \uc5c5\ub370\uc774\ud2b8\ud558\uc138\uc694!" + ], + "remote-disable-warning": "\uc774 \ubc84\uc804\uc758 QuickShop\uc740 \uc6d0\uaca9 \uc11c\ubc84\uc5d0 \uc758\ud574 \ube44\ud65c\uc131\ud654\ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4. \uc774 \ubc84\uc804\uc5d0\ub294 \uc2ec\uac01\ud55c \ubb38\uc81c\uac00 \uc788\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4. SpigotMC \ud398\uc774\uc9c0\uc5d0\uc11c \uc790\uc138\ud55c \ub0b4\uc6a9\uc744 \ud655\uc778\ud558\uc2ed\uc2dc\uc624 : {0}.\uc774 \uacbd\uace0\ub294 \ub2f9\uc2e0\uc758 \ucf58\uc194\uc5d0 \ud5c8\uac00\ub41c \ubc84\uc804\uc744 \uc0ac\uc6a9\ud560 \ub54c\uae4c\uc9c0 \ub730 \uac83\uc785\ub2c8\ub2e4. \uc11c\ubc84 \uad6c\ub3d9\uc5d0\ub294 \uc601\ud5a5\uc744 \uc8fc\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.", + "label": { + "unstable": "[\ubd88\uc548\uc815\ud568]", + "stable": "[\uc548\uc815\ub428]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&c{0} \uc704\uce58\uc5d0 \uc788\ub294 \ub2f9\uc2e0\uc758 \uc0c1\uc810\uc774 \uc720\uc9c0 \ube44\uc6a9\uc774 \uc5c6\uc5b4 \uc81c\uac70\ub418\uc5c8\uc2b5\ub2c8\ub2e4!", + "digits-reach-the-limit": "&c\uac00\uaca9\uc758 \uc18c\uc218\uc810 \ub4a4 \uc22b\uc790 \uac1c\uc218\uc758 \ud55c\uacc4\uc5d0 \ub3c4\ub2ec\ud588\uc2b5\ub2c8\ub2e4.", + "complete": "&a\uc644\ub8cc!" +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/pl.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/pl.json new file mode 100644 index 0000000..292e2fa --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/pl.json @@ -0,0 +1,234 @@ +{ + "translation-author": "T\u0142umacz: NieOGEL, NeonDmn i PLKaratusPL", + "translation-version": "Wspierana wersja: Reremake", + "translation-contributors": "Wsp\u00f3\u0142autorzy: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "J\u0119zyk: Polski (pl_PL)", + "language-version": "27", + "not-looking-at-shop": "&cNie znaleziono sklepu, musisz patrze\u0107 si\u0119 na sklep.", + "no-anythings-in-your-hand": "&cW twojej r\u0119ce nic nie ma.", + "no-permission": "Nie masz na to uprawnie\u0144.", + "no-creative-break": "&cNie mo\u017cesz niszczy\u0107 sklep\u00f3w innych graczy w trybie kreatywnym. Zamiast tego u\u017cyj trybu przetrwania.", + "no-double-chests": "&cNie mo\u017cesz stworzy\u0107 sklepu z podw\u00f3jn\u0105 skrzyni\u0105.", + "shop-already-owned": "&cTo ju\u017c jest sklep.", + "chest-was-removed": "&cSklep zosta\u0142 usuni\u0119ty.", + "price-too-cheap": "&cCena musi by\u0107 wi\u0119ksza ni\u017c &e${0}", + "no-price-change": "&cCena nie zosta\u0142a zmieniona!", + "you-cant-afford-a-new-shop": "&cMusisz mie\u0107 {0} aby zrobi\u0107 nowy sklep.", + "player-bought-from-your-store-tax": "&c{0} zakupi\u0142 {1} {2} z twojego sklepu, i zap\u0142aci\u0142 {3} podatku.", + "you-cant-afford-to-change-price": "&cMusisz mie\u0107 {0} aby zmieni\u0107 cen\u0119 w sklepie.", + "success-created-shop": "&aUtworzono sklep.", + "success-removed-shop": "&aSklep usuni\u0119ty.", + "shops-arent-locked": "&cPami\u0119taj, \u017ce sklepy NIE s\u0105 chronione przed kradzie\u017c\u0105! Je\u015bli chcesz zatrzyma\u0107 z\u0142odziei, zamknij je za pomoc\u0105 LWC, Lockette itd.!", + "shop-creation-cancelled": "&cAnulowano tworzenie sklepu.", + "shop-purchase-cancelled": "&cAnulowano zakup w sklepie.", + "shop-stock-too-low": "&cW sklepie zosta\u0142o {0} {1} przedmiot\u00f3w", + "you-cant-afford-to-buy": "&cTo kosztuje {0}, a ty masz tylko {1}", + "negative-amount": "&cYYY... nie mo\u017cna u\u017cywa\u0107 ujemnych cen xD", + "not-a-number": "&cMo\u017ce by\u0107 tylko liczba, ale wpiszesz {0}", + "not-a-integer": "&cMo\u017ce by\u0107 tylko liczba ca\u0142kowita, ale wpiszesz {0}", + "player-bought-from-your-store": "&c{0} kupi\u0142 {1} {2} z twojego sklepu.", + "shop-out-of-stock": "&5W twoim sklepie {0}, {1}, {2}, zabrak\u0142o {3}", + "shop-has-no-space": "&cSklep ma miejsce tylko na {0} wi\u0119cej {1}.", + "you-dont-have-that-many-items": "&cPosiadasz tylko {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cTo kosztuje {0} ale w\u0142a\u015bciciel ma tylko {1}", + "player-sold-to-your-store": "&a{0} sprzeda\u0142 ci {1} {2}.", + "shop-out-of-space": "&5Tw\u00f3j sklep na {0}, {1}, {2}, jest ju\u017c pe\u0142ny.", + "fee-charged-for-price-change": "&aZap\u0142aci\u0142e\u0107 &c{0}&a zmieniaj\u0105c cen\u0119.", + "price-is-now": "&aNowa cena sklepu to &e{0}", + "thats-not-a-number": "&cNieprawid\u0142owa liczba", + "no-price-given": "&cPodaj poprawn\u0105 cen\u0119.", + "average-price-nearby": "&a\u015arednia cena w pobli\u017cu: &e{0}", + "shop-has-changed": "&cSklep, kt\u00f3ry u\u017cywasz zmieni\u0142 si\u0119 w trakcie!", + "shop-not-exist": "&cSklep nie istnieje.", + "nearby-shop-this-way": "&aSklep jest {0} blok\u00f3w od ciebie.", + "no-nearby-shop": "&cBrak w pobli\u017cu sklep\u00f3w pasuj\u0105cych do {0}.", + "buying-more-than-selling": "&cUWAGA: Kupujesz przedmioty za wi\u0119cej ni\u017c sprzedajesz!", + "not-enough-space": "&cMasz miejsce tylko na kolejne {0} przedmiot\u00f3w!", + "refill-success": "&aNape\u0142niono", + "empty-success": "&aWyczyszczono", + "admin-shop": "AdminShop", + "unknown-owner": "Nieznany", + "owner-bypass-check": "&eWszystkie sprawdzania zosta\u0142y pomini\u0119te. Wymiana udana! (Jeste\u015b w\u0142a\u015bcicielem sklepu)", + "reached-maximum-can-create": "&cJu\u017c posiadasz maksymaln\u0105 liczb\u0119 sklep\u00f3w: {0}\/{1}", + "restricted-prices": "&cCena ograniczona dla {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cNie mia\u0142e\u015b wystarczaj\u0105co pieni\u0119dzy, by utrzyma\u0107 swoje sklepy! Wszystkie sklepy zosta\u0142y teraz usuni\u0119te...", + "nothing-to-flush": "&aBrak nowych wiadomo\u015bci ze sklep\u00f3w.", + "break-shop-use-supertool": "&eMo\u017cesz rozbi\u0107 sklep za pomoc\u0105 SuperTool.", + "failed-to-put-sign": "&cZa ma\u0142o miejsca, by umie\u015bci\u0107 tabliczk\u0119.", + "failed-to-paste": "&cNie uda\u0142o si\u0119 przes\u0142a\u0107 danych do Pastebin. Sprawd\u017a po\u0142\u0105czenie z internetem i spr\u00f3buj ponownie. (Szczeg\u00f3\u0142owe informacje na ten temat w konsoli)", + "warn-to-paste": "&eGromadzenie danych i przesy\u0142anie ich do Pastebin mo\u017ce troch\u0119 potrwa\u0107. &c&lUwaga &c, dane s\u0105 upubliczniane przez tydzie\u0144, mo\u017ce to spowodowa\u0107 wyciek z konfiguracji serwera oraz innych poufnych danych, upewnij si\u0119, \u017ce wysy\u0142asz je tylko do swojego personelu\/dewelopera.", + "price-too-high": "&cZbyt wysoka cena sklepu! Nie mo\u017cna utworzy\u0107 takiego, kt\u00f3rego cena jest wy\u017csza ni\u017c {0}.", + "you-cant-create-shop-in-there": "&cNie masz uprawnie\u0144 do utworzenia sklepu w tej lokalizacji.", + "unknown-player": "&cGracz nie istnieje, sprawd\u017a nazw\u0119 u\u017cytkownika, kt\u00f3r\u0105 wpisa\u0142e\u015b.", + "shop-staff-cleared": "&aPomy\u015blnie usuni\u0119to wszystkich graczy z twojego sklepu.", + "shop-staff-added": "&aPomy\u015blnie dodano gracza {0} do twojego sklepu.", + "shop-staff-deleted": "&aPomy\u015blnie usuni\u0119to gracza {0} z twojego sklepu.", + "no-permission-build": "&cNie mo\u017cesz zrobi\u0107 tutaj sklepu.", + "success-change-owner-to-server": "&aZ powodzeniem zmieniono w\u0142a\u015bciciela sklepu na Server.", + "flush-finished": "&aPomy\u015blnie wyczyszczono wiadomo\u015bci.", + "purchase-failed": "&cZakup nieudany: B\u0142\u0105d wewn\u0119trzny, skontaktuj si\u0119 z administratorem.", + "no-pending-action": "&cNie masz \u017cadnych oczekuj\u0105cych dzia\u0142a\u0144", + "permission-denied-3rd-party": "&cOdmowa dost\u0119pu: wtyczka innej firmy [{0}]", + "menu": { + "successful-purchase": "&aZakupiono:", + "successfully-sold": "&aSprzedano:", + "item-name-and-price": "&e{0} {1} &aza &e{2}", + "sell-tax": "&aZap\u0142aci\u0142e\u015b &e{0} &aw podatkach.", + "sell-tax-self": "&aTo tw\u00f3j sklep, wi\u0119c nie p\u0142acisz podatk\u00f3w.", + "enchants": "&5Enchanty", + "stored-enchants": "&5Przechowywane Enchanty", + "shop-information": "&aInfo:", + "owner": "&aW\u0142a\u015bciciel: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Podgl\u0105d Itemu]", + "space": "&aMiejsce: &e{0}", + "stock": "&aIlo\u015b\u0107 &e{0}", + "price-per": "&aCena za &e{0} &a- &e{1}", + "total-value-of-chest": "&aIlo\u015b\u0107 w skrzyni: &e{0}", + "damage-percent-remaining": "&e{0}% &aZosta\u0142o.", + "this-shop-is-buying": "&aTen sklep &dSKUPUJE&a itemy.", + "this-shop-is-selling": "&aTen sklep &bSPRZEDAJE&a itemy.", + "effects": "&aEfekty", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cOmijanie blokady Quick Shop!", + "that-is-locked": "&cTen sklep jest zamkni\u0119ty.", + "how-many-buy": "&aWpisz ilo\u015b\u0107 jak\u0105 chcesz &bKUPI\u0106&a na chat. Wpisz &ball&a, je\u015bli chcesz kupi\u0107 wszystko.", + "how-many-sell": "&aWpisz ilo\u015b\u0107 jak\u0105 chcesz &dSPRZEDA\u0106&a na chat. Posiadasz &e{0}&a przedmiot\u00f3w. Wpisz &ball&a, je\u015bli chcesz sprzeda\u0107 wszystko.", + "not-allowed-to-create": "&cTu nie zrobisz sklepu.", + "blacklisted-item": "&cTen item jest na czarnej li\u015bcie. Nie mo\u017cesz go sprzedawa\u0107", + "how-much-to-trade-for": "&aPodaj cen\u0119 przedmiotu &e{0}&a na chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aSklep jest teraz nielimitowany", + "limited": "&aSklep jest teraz limitowany" + }, + "no-owner-given": "&cNie podano w\u0142a\u015bciciela. U\u017cyj &a\/qs setowner &c", + "new-owner": "&aNowy W\u0142a\u015bciciel: &e{0}", + "now-buying": "&aTeraz &dSKUPUJESZ&a &e{0}", + "now-selling": "&aTeraz &dSPRZEDAJESZ&a &e{0}", + "cleaning": "&aUsuwanie sklep\u00f3w z pustymi inwentarzami...", + "reloading": "&aPrze\u0142adowanie...", + "cleaned": "&aUsuni\u0119to &e{0}&aze sklepu", + "no-type-given": "&cU\u017cycie: \/qs find ", + "no-amount-given": "&cNie podano ilo\u015bci. U\u017cyj &a\/qs refill &c", + "now-debuging": "&aPomy\u015blnie prze\u0142\u0105czono si\u0119 do trybu developerskiego. Prze\u0142aduj QuickShop...", + "now-nolonger-debuging": "&aPomy\u015blnie prze\u0142\u0105czono si\u0119 do trybu produkcji. Prze\u0142aduj QuickShop...", + "wrong-args": "&cOpcja nie istnieje, u\u017cyj \/qs help aby uzyska\u0107 pomoc.", + "description": { + "title": "&aPomoc QuickShop", + "unlimited": "&eTworzy nielimitowany sklep", + "setowner": "&eZmie\u0144 w\u0142a\u015bciciela sklepu", + "owner": "&eZmie\u0144 w\u0142a\u015bciciela sklepu", + "buy": "&eZmie\u0144 rodzaj sklepu na tryb &dKUP", + "sell": "&eZmie\u0144 rodzaj sklepu na tryb &bSPRZEDA\u017b", + "price": "&eZmie\u0144 cen\u0119 kupna\/sprzeda\u017cy w sklepie", + "clean": "&eUsuwa wszystkie (za\u0142adowane) sklepy z pustym inwentarzem", + "find": "&eLokalizuje najbli\u017cszy sklep okre\u015blonego typu.", + "reload": "&ePrze\u0142adowuje plik config.yml dla QuickShop.", + "refill": "&eDodaje dan\u0105 liczb\u0119 przedmiot\u00f3w do sklepu", + "empty": "&eUsuwa ca\u0142y zapas ze sklepu", + "debug": "&ePrzejd\u017a w tryb deweloperski", + "create": "&eTworzy nowy sklep na skrzyni", + "fetchmessage": "&ePobierz nieprzeczytan\u0105 wiadomo\u015b\u0107 ze sklepu", + "info": "&ePoka\u017c statystyki QuickShop", + "paste": "&eAutomatyczny upload danych serwera do Pastebin", + "staff": "&eZarz\u0105dzaj personelem sklepu", + "remove": "&eUsuni\u0119to sklep na kt\u00f3ry patrzysz", + "amount": "&eWykonaj za swoje dzia\u0142ania z kwot\u0105 (w przypadku problemu z wtyczk\u0105 czatu)", + "about": "&ePoka\u017c informacj\u0119 o QuickShop", + "help": "&ePoka\u017c pomoc dla QuickShop", + "supercreate": "&eUtw\u00f3rz sklep z obej\u015bciem ochrony" + } + }, + "signs": { + "selling": "Kup {0}", + "header": "&c{0}", + "buying": "Sprzedaj {0}", + "item": "{0}", + "price": "{0} za 1 szt.", + "unlimited": "Nielimitowany" + }, + "controlpanel": { + "setowner": "&aW\u0142a\u015bciciel: &b{0} &e[&d&lZmie\u0144&e]", + "infomation": "&aPanel kontrolny sklepu:", + "setowner-hover": "&eKliknij, aby zmieni\u0107 w\u0142a\u015bciciela.", + "unlimited": "&aNielimitowany: {0} &e[&d&lZmie\u0144&e]", + "unlimited-hover": "&eKliknij, aby prze\u0142\u0105czy\u0107, je\u015bli sklep jest nielimitowany.", + "mode-selling": "&aTryb sklepu: &bSPRZEDA\u017b &e[&d&lZmie\u0144&e]", + "mode-selling-hover": "&eKliknij, aby zmieni\u0107 sklep na tryb kupowania.", + "mode-buying": "&aTryb sklepu: &bKUP &e[&d&lZmie\u0144&e]", + "mode-buying-hover": "&eKliknij, aby zmieni\u0107 sklep na tryb sprzedawania.", + "price": "&aCena: &b{0} &e[&d&lUstaw&e]", + "price-hover": "&eKliknij, aby ustawi\u0107 now\u0105 cen\u0119 dla sklepu.", + "refill": "&aUzupe\u0142nianie: Uzupe\u0142nij sklep &e[&d&lOK&e]", + "refill-hover": "&eKliknij, aby uzupe\u0142ni\u0107 sklep.", + "empty": "&aCzyszczenie: Wyczy\u015b\u0107 sklep &e[&d&lOK&e]", + "empty-hover": "&eKliknij, aby wyczy\u015bci\u0107 sklep.", + "remove": "&c&l[Usu\u0144 sklep]", + "remove-hover": "&eKliknij, \u017ceby usun\u0105\u0107 sklep.", + "commands": { + "setowner": "\/qs setowner [Gracz]", + "unlimited": "\/qs slientunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [Nowa cena]", + "refill": "\/qs refill [Ilo\u015b\u0107]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a\u2714", + "failed": "&c\u2718" + }, + "tabcomplete": { + "price": "[cena]", + "range": "[zakres]", + "amount": "[ilo\u015b\u0107]" + }, + "updatenotify": { + "buttontitle": "[Aktualizuj Teraz]", + "onekeybuttontitle": "[Aktualizacja OneKey]", + "list": [ + "Wersja {0} jest ju\u017c dost\u0119pna! Wci\u0105\u017c u\u017cywasz {1}!", + "BUM!!! Nowy update! {0}", + "Niespodzianka! Nowy update {0}. Wci\u0105\u017c u\u017cywasz {1}!", + "Wygl\u0105da na to, \u017ce przyda ci si\u0119 ma\u0142a zmiana wersji. Wersja {0} jest ju\u017c dost\u0119pna!", + "Ups! Wersja {0} jest ju\u017c dost\u0119pna! A ty wci\u0105\u017c na {1}...", + "Zaufaj mi, nowy update {0} ju\u017c jest, czemu by nie skorzysta\u0107?", + "\u0141adowanie skl... a jednak nie :D |UPDATE {0}|!", + "Hmm.. tak, tak... diagnozuj\u0119 update {0}!", + "OMG! W\u0142a\u015bnie wysz\u0142o {0}, dlaczego ci\u0105gle siedzisz na {1}?", + "Dzisiaj w faktach po faktach: {0} ju\u017c jest!", + "Przed dalszym u\u017cytkowaniem {1} skontaktuj si\u0119 z lekarzem, lub farmaceut\u0105, lub u\u017cyj {0}.", + "Jeste\u015b naszym 1.000.000 klientem! Wygra\u0142e\u015b update do {0}!", + "Adminie! Twoje kr\u00f3lestwo jest zagro\u017cone, nalegam na przej\u015bcie do wersji {0}!", + "Nie, przyjacielu! Patrz na mnie! Stara wersja przeminie {0}, nowa {1} jest wieczna!", + "Ahhhhhhh! Nowy update {0}! Pobieraj Teraz!", + "S\u0142ysza\u0142e\u015b? Wersja {0} ju\u017c jest!" + ], + "remote-disable-warning": "&cTa wersja QuickShop jest oznaczona jako wy\u0142\u0105czona przez zdalny serwer, co oznacza, \u017ce ta wersja mo\u017ce mie\u0107 powa\u017cny problem, pobierz szczeg\u00f3\u0142y ze strony SpigotMC: {0}. To ostrze\u017cenie b\u0119dzie si\u0119 wy\u015bwietla\u0107 i spamowa\u0107 konsol\u0119, dop\u00f3ki nie u\u017cyjesz innej, nie wy\u0142\u0105czonej wersji, kt\u00f3ra nie wyp\u0142ywa na dzia\u0142anie serwera.", + "label": { + "unstable": "[Niestabilny]", + "stable": "[Stabilny]", + "lts": "[LTS]", + "qualityverifyed": "[Jako\u015b\u0107]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Mistrz]" + } + }, + "shop-removed-cause-ongoing-fee": "&cTw\u00f3j sklep w {0} zosta\u0142 usuni\u0119ty, poniewa\u017c nie mia\u0142e\u015b wystarczaj\u0105co du\u017co pieni\u0119dzy, aby go utrzyma\u0107!", + "digits-reach-the-limit": "&cOsi\u0105gn\u0105\u0142e\u015b limit cyfr po kropce w cenie.", + "complete": "&aZako\u0144czony!" +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/ru.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/ru.json new file mode 100644 index 0000000..4c9f8f0 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/ru.json @@ -0,0 +1,234 @@ +{ + "translation-author": "\u041f\u0435\u0440\u0435\u0432\u043e\u0434\u0447\u0438\u043a\u0438: Redase, turikhay", + "translation-version": "\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f: Reremake", + "translation-contributors": "\u0410\u0432\u0442\u043e\u0440\u044b: Timtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "\u042f\u0437\u044b\u043a\u043e\u0432\u043e\u0439 \u0440\u0435\u0433\u0438\u043e\u043d: \u0420\u0443\u0441\u0441\u043a\u0438\u0439 (ru_RU)", + "language-version": "27", + "not-looking-at-shop": "&cQuickShop \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d. \u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u0441\u0443\u043d\u0434\u0443\u043a.", + "no-anythings-in-your-hand": "&c\u0423 \u0432\u0430\u0441 \u043d\u0435\u0442 \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043e\u0432 \u0432 \u0440\u0443\u043a\u0430\u0445.", + "no-permission": "&c\u0423 \u0432\u0430\u0441 \u043d\u0435\u0442 \u043f\u0440\u0430\u0432 \u043d\u0430 \u044d\u0442\u043e.", + "no-creative-break": "&c\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043b\u043e\u043c\u0430\u0442\u044c \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u044b \u0434\u0440\u0443\u0433\u0438\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432 \u0432 \u043a\u0440\u0435\u0430\u0442\u0438\u0432\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435. \u0414\u0435\u043b\u0430\u0439\u0442\u0435 \u044d\u0442\u043e \u0432 \u0432\u044b\u0436\u0438\u0432\u0430\u043d\u0438\u0438.", + "no-double-chests": "&c\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u0438\u0437 \u0434\u0432\u043e\u0439\u043d\u043e\u0433\u043e \u0441\u0443\u043d\u0434\u0443\u043a\u0430.", + "shop-already-owned": "&c\u042d\u0442\u043e \u0443\u0436\u0435 \u043c\u0430\u0433\u0430\u0437\u0438\u043d.", + "chest-was-removed": "&c\u0421\u0443\u043d\u0434\u0443\u043a \u0431\u044b\u043b \u0443\u0434\u0430\u043b\u0435\u043d.", + "price-too-cheap": "&c\u0426\u0435\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 &e${0}", + "no-price-change": "&c\u042d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043d\u0435 \u043f\u0440\u0438\u0432\u0435\u043b\u043e \u043a \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044e \u0446\u0435\u043d\u044b!", + "you-cant-afford-a-new-shop": "&c\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430 \u0441\u0442\u043e\u0438\u0442 {0}.", + "player-bought-from-your-store-tax": "&c{0} \u043a\u0443\u043f\u0438\u043b {1} {2} \u0432 \u0432\u0430\u0448\u0435\u043c \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435, \u0438 \u0432\u044b \u0437\u0430\u043f\u043b\u0430\u0442\u0438\u043b\u0438 {3} \u043d\u0430\u043b\u043e\u0433\u0430.", + "you-cant-afford-to-change-price": "&c\u0421\u043c\u0435\u043d\u0430 \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u0432\u0430\u0448\u0435\u043c \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435 \u0441\u0442\u043e\u0438\u0442 {0}.", + "success-created-shop": "&a\u041c\u0430\u0433\u0430\u0437\u0438\u043d \u0441\u043e\u0437\u0434\u0430\u043d.", + "success-removed-shop": "&a\u041c\u0430\u0433\u0430\u0437\u0438\u043d \u0443\u0434\u0430\u043b\u0451\u043d.", + "shops-arent-locked": "&c\u041f\u043e\u043c\u043d\u0438\u0442\u0435, \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u044b \u041d\u0415 \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u044b \u043e\u0442 \u043a\u0440\u0430\u0436! \u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u043e\u0440\u043e\u0432, \u0437\u0430\u0449\u0438\u0449\u0430\u0439\u0442\u0435 \u0441\u0443\u043d\u0434\u0443\u043a\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e LWC, Lockette, \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u0438\u0432\u0430\u0442\u0430 \u0441\u0443\u043d\u0434\u0443\u043a\u043e\u0432!", + "shop-creation-cancelled": "&c\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430 \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u043e.", + "shop-purchase-cancelled": "&c\u041f\u043e\u043a\u0443\u043f\u043a\u0430 \u0432 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435 \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430.", + "shop-stock-too-low": "&c\u0412 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043b\u0438\u0448\u044c {0} {1}", + "you-cant-afford-to-buy": "&c\u042d\u0442\u043e \u0441\u0442\u043e\u0438\u0442 {0}, \u043d\u043e \u0443 \u0432\u0430\u0441 \u0442\u043e\u043b\u044c\u043a\u043e {1}", + "negative-amount": "&c\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e", + "not-a-number": "&c\u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u043e\u043c\u0435\u0440, \u043d\u043e \u0432\u044b \u0432\u0432\u043e\u0434\u0438\u0442\u0435 {0}", + "not-a-integer": "&c\u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0446\u0435\u043b\u043e\u0435 \u0447\u0438\u0441\u043b\u043e, \u043d\u043e \u0432\u044b \u0432\u0432\u043e\u0434\u0438\u0442\u0435 {0}", + "player-bought-from-your-store": "&c{0} \u043a\u0443\u043f\u0438\u043b {1} {2} \u0432 \u0432\u0430\u0448\u0435\u043c \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435.", + "shop-out-of-stock": "&5\u0412\u0430\u0448 \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u043d\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u0445 {0}, {1}, {2}, \u0438\u0441\u0447\u0435\u0440\u043f\u0430\u043b \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e {3}", + "shop-has-no-space": "&c\u041c\u0430\u0433\u0430\u0437\u0438\u043d \u043c\u043e\u0436\u0435\u0442 \u0432\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0435\u0449\u0451 {0} {1}.", + "you-dont-have-that-many-items": "&c\u0423 \u0432\u0430\u0441 \u0442\u043e\u043b\u044c\u043a\u043e {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&c\u042d\u0442\u043e \u0441\u0442\u043e\u0438\u0442 {0} \u043d\u043e \u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u0438\u043c\u0435\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e {1}", + "player-sold-to-your-store": "&a{0} \u043f\u0440\u043e\u0434\u0430\u043b {1} {2} \u0432\u0430\u0448\u0435\u043c\u0443 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0443.", + "shop-out-of-space": "&5\u0412\u0430\u0448 \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u043d\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u0445 {0}, {1}, {2}, \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043b\u043e\u043d.", + "fee-charged-for-price-change": "&a\u0417\u0430\u043f\u043b\u0430\u0442\u0438\u0442\u0435 &c{0}&a \u0447\u0442\u043e\u0431\u044b \u0441\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c.", + "price-is-now": "&a\u041d\u043e\u0432\u0430\u044f \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u0432 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435 \u044d\u0442\u043e &e{0}", + "thats-not-a-number": "&c\u041d\u0435\u0432\u0435\u0440\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435", + "no-price-given": "&c\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u0443\u043a\u0430\u0436\u0438\u0442\u0435 \u0432\u0435\u0440\u043d\u0443\u044e \u0446\u0435\u043d\u0443.", + "average-price-nearby": "&a\u0421\u0440\u0435\u0434\u043d\u044f\u044f \u0446\u0435\u043d\u0430: &e{0}", + "shop-has-changed": "&c\u041c\u0430\u0433\u0430\u0437\u0438\u043d, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0432\u044b \u043f\u044b\u0442\u0430\u0435\u0442\u0435\u0441\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c, \u0431\u044b\u043b \u0438\u0437\u043c\u0435\u043d\u0435\u043d", + "shop-not-exist": "&c\u0417\u0434\u0435\u0441\u044c \u043d\u0435 \u0431\u044b\u043b\u043e \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430.", + "nearby-shop-this-way": "&a\u041c\u0430\u0433\u0430\u0437\u0438\u043d \u0432 {0} \u0431\u043b\u043e\u043a\u0430\u0445 \u043e\u0442 \u0432\u0430\u0441.", + "no-nearby-shop": "&c\u041d\u0435\u0442 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u043e\u0432, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 {0} \u043f\u043e\u0431\u043b\u0438\u0437\u043e\u0441\u0442\u0438.", + "buying-more-than-selling": "&c\u0412\u041d\u0418\u041c\u0410\u041d\u0418\u0415: \u0412\u044b \u043f\u043e\u043a\u0443\u043f\u0430\u0435\u0442\u0435 \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u044b \u0434\u043e\u0440\u043e\u0436\u0435 \u0447\u0435\u043c \u043f\u0440\u043e\u0434\u0430\u0451\u0442\u0435!", + "not-enough-space": "&c\u0423 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043c\u0435\u0441\u0442\u043e \u0435\u0449\u0451 \u0434\u043b\u044f {0} \u044d\u0442\u043e\u0433\u043e!", + "refill-success": "&a\u041f\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e", + "empty-success": "&a\u041e\u043f\u0443\u0441\u0442\u043e\u0448\u0435\u043d\u0438\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e", + "admin-shop": "\u041c\u0430\u0433\u0430\u0437\u0438\u043d \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438", + "unknown-owner": "\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e", + "owner-bypass-check": "&e\u0412\u0441\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u044b, \u0443\u0434\u0430\u0447\u043d\u0430\u044f \u0441\u0434\u0435\u043b\u043a\u0430! (\u0412\u044b \u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430)", + "reached-maximum-can-create": "&c\u0412\u044b \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c {0}\/{1} \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u043e\u0432!", + "restricted-prices": "&c\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0435 \u0446\u0435\u043d\u044b \u0434\u043b\u044f {0}: \u043c\u0438\u043d\u0438\u043c\u0443\u043c {1}, \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c {2}", + "no-enough-money-to-keep-shops": "&c\u0423 \u0432\u0430\u0441 \u043d\u0435 \u0445\u0432\u0430\u0442\u0438\u043b\u043e \u0434\u0435\u043d\u0435\u0433, \u0447\u0442\u043e\u0431\u044b \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u044b! \u0412\u0441\u0435 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u044b \u0443\u0434\u0430\u043b\u0435\u043d\u044b...", + "nothing-to-flush": "&a\u0423 \u0432\u0430\u0441 \u043d\u0435\u0442 \u043d\u043e\u0432\u044b\u0445 \u043f\u0440\u043e\u0434\u0430\u0436 \u0432 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430\u0445.", + "break-shop-use-supertool": "&e\u0412\u044b \u0441\u043b\u043e\u043c\u0430\u043b\u0438 \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e SuperTool.", + "failed-to-put-sign": "&c\u041d\u0435\u0442 \u043c\u0435\u0441\u0442\u0430 \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0443.", + "failed-to-paste": "&c\u041e\u0448\u0438\u0431\u043a\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0432 Pastebin, \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0443. (\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438).", + "warn-to-paste": "&e\u0421\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0432 Pastebin, \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043d\u044f\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f. &c&l\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435&c, \u0434\u0430\u043d\u043d\u044b\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0439 \u043d\u0435\u0434\u0435\u043b\u0438, \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u0443\u0442\u0435\u0447\u043a\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0432\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0435 \u0438\u0445 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0432\u043e\u0435\u043c\u0443 \u0434\u043e\u0432\u0435\u0440\u0435\u043d\u043d\u043e\u043c\u0443 \u043b\u0438\u0446\u0443 \/ \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443.", + "price-too-high": "&c\u0421\u043b\u0438\u0448\u043a\u043e\u043c \u0432\u044b\u0441\u043e\u043a\u0430\u044f \u0446\u0435\u043d\u0430 \u0432 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435! \u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0446\u0435\u043d\u0443 \u0432\u044b\u0448\u0435, \u0447\u0435\u043c {0}.", + "you-cant-create-shop-in-there": "&c\u0423 \u0432\u0430\u0441 \u043d\u0435\u0442 \u043f\u0440\u0430\u0432 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u044b \u0432 \u044d\u0442\u043e\u043c \u043c\u0435\u0441\u0442\u0435.", + "unknown-player": "&c\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0438\u0433\u0440\u043e\u043a \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0435\u0433\u043e \u0438\u043c\u044f.", + "shop-staff-cleared": "&a\u0423\u0441\u043f\u0435\u0448\u043d\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u044b \u0432\u0441\u0435 \u0441\u043e\u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u044b.", + "shop-staff-added": "&a {0} \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0432 \u0441\u043e\u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u044b \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430.", + "shop-staff-deleted": "&a {0} \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0443\u0434\u0430\u043b\u0435\u043d \u0438\u0437 \u0441\u043e\u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0435\u0432 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430.", + "no-permission-build": "&c\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u0432 \u044d\u0442\u043e\u043c \u043c\u0435\u0441\u0442\u0435.", + "success-change-owner-to-server": "&a\u0421\u0435\u0440\u0432\u0435\u0440 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u043a\u0430\u043a \u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430.", + "flush-finished": "&a\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043e\u0447\u0438\u0449\u0435\u043d\u044b.", + "purchase-failed": "&c\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u043a\u0443\u043f\u043a\u0438: \u041e\u0448\u0438\u0431\u043a\u0430, \u0441\u0432\u044f\u0436\u0438\u0442\u0435\u0441\u044c \u0441 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0430.", + "no-pending-action": "&c\u0423 \u0432\u0430\u0441 \u043d\u0435\u0442 \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439", + "permission-denied-3rd-party": "&c\u0414\u043e\u0441\u0442\u0443\u043f \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d: \u0421\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0439 \u043f\u043b\u0430\u0433\u0438\u043d [{0}].", + "menu": { + "successful-purchase": "&a\u0412\u044b \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u043b\u0438:", + "successfully-sold": "&a\u0412\u044b \u043f\u0440\u043e\u0434\u0430\u043b\u0438:", + "item-name-and-price": "&e{0} {1} &a\u0437\u0430 &e{2}", + "sell-tax": "&a\u041d\u0430\u043b\u043e\u0433 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u043b &e{0} &ain.", + "sell-tax-self": "&a\u0412\u044b \u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u044d\u0442\u043e\u0433\u043e \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441 \u0432\u0430\u0441 \u043d\u0435 \u0432\u0437\u044f\u0442\u044c \u043d\u0430\u043b\u043e\u0433.", + "enchants": "&5\u0427\u0430\u0440\u044b", + "stored-enchants": "&5\u041d\u0430\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0447\u0430\u0440\u044b", + "shop-information": "&a\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435:", + "owner": "&a\u0412\u043b\u0430\u0434\u0435\u043b\u0435\u0446: {0}", + "item": "&a\u041f\u0440\u0435\u0434\u043c\u0435\u0442: &e{0}", + "preview": "&b[\u041f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u0430]", + "space": "&a\u0421\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e: &e{0}", + "stock": "&a\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e: &e{0}", + "price-per": "&a\u0426\u0435\u043d\u0430 \u0437\u0430 &e{0} &a- &e{1}", + "total-value-of-chest": "&a\u0412\u0441\u0435\u0433\u043e \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u043e\u0432: &e{0}", + "damage-percent-remaining": "&e{0}% &a\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c.", + "this-shop-is-buying": "&a\u042d\u0442\u043e\u0442 \u043c\u0430\u0433\u0430\u0437\u0438\u043d &d\u041f\u041e\u041a\u0423\u041f\u0410\u0415\u0422&a \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u044b.", + "this-shop-is-selling": "&a\u042d\u0442\u043e\u0442 \u043c\u0430\u0433\u0430\u0437\u0438\u043d &b\u041f\u0420\u041e\u0414\u0410\u0415\u0422&a \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u044b.", + "effects": "&a\u042d\u0444\u0444\u0435\u043a\u0442\u044b", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&c\u041e\u0431\u0445\u043e\u0434 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 QuickShop!", + "that-is-locked": "&c\u041c\u0430\u0433\u0430\u0437\u0438\u043d \u0437\u0430\u043a\u0440\u044b\u0442.", + "how-many-buy": "&a\u041d\u0430\u043f\u0438\u0448\u0438\u0442\u0435 \u0432 \u0447\u0430\u0442 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043e\u0432 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 &b\u041a\u0423\u041f\u0418\u0422\u042c&a. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043a\u0443\u043f\u0438\u0442\u044c &e {0} &a. \u0412\u0432\u0435\u0434\u0438\u0442\u0435 &ball&a \u0447\u0442\u043e\u0431\u044b \u043a\u0443\u043f\u0438\u0442\u044c \u0432\u0441\u0451.", + "how-many-sell": "&a\u041d\u0430\u043f\u0438\u0448\u0438\u0442\u0435 \u0432 \u0447\u0430\u0442 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043e\u0432 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 &d\u041f\u0420\u041e\u0414\u0410\u0422\u042c&a. \u0414\u043e\u0441\u0442\u0443\u043f\u043d\u043e: &e{0}&a. \u0412\u0432\u0435\u0434\u0438\u0442\u0435 &ball&a \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0434\u0430\u0442\u044c \u0432\u0441\u0451.", + "not-allowed-to-create": "&c\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u0437\u0434\u0435\u0441\u044c.", + "blacklisted-item": "&c\u042d\u0442\u043e\u0442 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0447\u0435\u0440\u043d\u043e\u043c \u0441\u043f\u0438\u0441\u043a\u0435. \u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u0434\u0430\u0432\u0430\u0442\u044c \u0435\u0433\u043e.", + "how-much-to-trade-for": "&a\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0432 \u0447\u0430\u0442 \u0446\u0435\u043d\u0443, \u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u043e\u0434\u0430\u0442\u044c &e{0}.", + "command": { + "toggle-unlimited": { + "unlimited": "&a\u041c\u0430\u0433\u0430\u0437\u0438\u043d \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d", + "limited": "&a\u041c\u0430\u0433\u0430\u0437\u0438\u043d \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d" + }, + "no-owner-given": "&c\u0412\u043b\u0430\u0434\u0435\u043b\u0435\u0446 \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 &a\/qs setowner &c", + "new-owner": "&a\u041d\u043e\u0432\u044b\u0439 \u0432\u043b\u0430\u0434\u0435\u043b\u0435\u0446: &e{0}", + "now-buying": "&a\u042d\u0442\u043e\u0442 \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u0442\u0435\u043f\u0435\u0440\u044c &d\u041f\u041e\u041a\u0423\u041f\u0410\u0415\u0422&a &e{0}", + "now-selling": "&a\u042d\u0442\u043e\u0442 \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u0442\u0435\u043f\u0435\u0440\u044c &b\u041f\u0420\u041e\u0414\u0410\u0415\u0422 &e{0}", + "cleaning": "&a\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u0443\u0441\u0442\u044b\u0445 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u043e\u0432...", + "reloading": "&a\u041f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e...", + "cleaned": "&a\u041e\u0447\u0438\u0449\u0435\u043d\u043e &e{0}&a \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u043e\u0432", + "no-type-given": "&c\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c: \/qs find <\u043f\u0440\u0435\u0434\u043c\u0435\u0442>", + "no-amount-given": "&c\u0421\u0443\u043c\u043c\u0430 \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0430. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 &a\/qs refill <\u0447\u0438\u0441\u043b\u043e>&c", + "now-debuging": "&a\u0423\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0432 \u0440\u0435\u0436\u0438\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430. \u041f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e QuickShop...", + "now-nolonger-debuging": "&a\u0423\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0432 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c. \u041f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e QuickShop...", + "wrong-args": "&c\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442, \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \/qs help \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0438.", + "description": { + "title": "&aQuickShop \u0441\u043f\u0440\u0430\u0432\u043a\u0430", + "unlimited": "&e\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u043c", + "setowner": "&e\u0421\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430", + "owner": "&e\u0421\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430", + "buy": "&e\u041f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u0432 \u0440\u0435\u0436\u0438\u043c &d\u041f\u041e\u041a\u0423\u041f\u041a\u0410", + "sell": "&e\u041f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u0432 \u0440\u0435\u0436\u0438\u043c &d\u041f\u0420\u041e\u0414\u0410\u0416\u0410", + "price": "&e\u0421\u043c\u0435\u043d\u0438\u0442\u044c \u0446\u0435\u043d\u0443 \u043f\u043e\u043a\u0443\u043f\u043a\u0438\/\u043f\u0440\u043e\u0434\u0430\u0436\u0438 \u0432\u0430\u0448\u0435\u0433\u043e \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430", + "clean": "&e\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u0441\u0435 \u043f\u0443\u0441\u0442\u044b\u0435 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u044b (0 \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043e\u0432)", + "find": "&e\u041d\u0430\u0445\u043e\u0434\u0438\u0442 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0439 \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430.", + "reload": "&a\u041f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0438\u0437 config.yml.", + "refill": "&e\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043e\u0432 \u0432 \u043c\u0430\u0433\u0430\u0437\u0438\u043d", + "empty": "&e\u0423\u0434\u0430\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 \u0442\u043e\u0432\u0430\u0440\u044b \u0438\u0437 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430", + "debug": "&e\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u0432 \u0440\u0435\u0436\u0438\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430", + "create": "&e\u0421\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u0438\u0437 \u0441\u0443\u043d\u0434\u0443\u043a\u0430 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435", + "fetchmessage": "&e\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0435\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435", + "info": "&e\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 QuickShop", + "paste": "&e\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0432 Pastebin", + "staff": "&e\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430\u043c\u0438 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430", + "remove": "&e\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&e\u041e QuickShop", + "help": "&e\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0443 QuickShop", + "supercreate": "&e\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u0432 \u043e\u0431\u0445\u043e\u0434 \u0432\u0441\u0435\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0437\u0430\u0449\u0438\u0442\u044b" + } + }, + "signs": { + "selling": "\u041f\u0440\u043e\u0434\u0430\u0451\u0442 {0}", + "header": "&c{0}", + "buying": "\u041f\u043e\u043a\u0443\u043f\u0430\u0435\u0442 {0}", + "item": "{0}", + "price": "{0}", + "unlimited": "\u041c\u043d\u043e\u0433\u043e" + }, + "controlpanel": { + "setowner": "&a\u0412\u043b\u0430\u0434\u0435\u043b\u0435\u0446: &b{0} &e[&d&l\u0421\u043c\u0435\u043d\u0438\u0442\u044c&e]", + "infomation": "&a\u041f\u0430\u043d\u0435\u043b\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u043e\u043c:", + "setowner-hover": "&e\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u0434\u043b\u044f \u0441\u043c\u0435\u043d\u044b \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430.", + "unlimited": "&a\u0411\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439: {0} &e[&d&l\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c&e]", + "unlimited-hover": "&e\u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f, \u0435\u0441\u043b\u0438 \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u0411\u0415\u0421\u041a\u041e\u041d\u0415\u0427\u041d\u042b\u0419.", + "mode-selling": "&a\u0420\u0435\u0436\u0438\u043c: &b\u041f\u0440\u043e\u0434\u0430\u0436\u0430 &e[&d&l\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c&e]", + "mode-selling-hover": "&e\u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u0432 \u0440\u0435\u0436\u0438\u043c \u043f\u043e\u043a\u0443\u043f\u043a\u0438.", + "mode-buying": "&a\u0420\u0435\u0436\u0438\u043c: &b\u041f\u043e\u043a\u0443\u043f\u043a\u0430 &e[&d&l\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c&e]", + "mode-buying-hover": "&e\u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u0432 \u0440\u0435\u0436\u0438\u043c \u043f\u0440\u043e\u0434\u0430\u0436\u0438.", + "price": "&a\u0426\u0435\u043d\u0430: &b{0} &e[&d&l\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c&e]", + "price-hover": "&e\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043d\u043e\u0432\u043e\u0439 \u0446\u0435\u043d\u044b.", + "refill": "&a\u041f\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435: \u041f\u0435\u0440\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u0430\u043c\u0438 &e[&d&lOK&e]", + "refill-hover": "&e\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043c\u0430\u0433\u0430\u0437\u0438\u043d.", + "empty": "&a\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c: \u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0432\u0441\u0435 \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u044b \u0432 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435 &e[&d&lOK&e]", + "empty-hover": "&e\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u0447\u0442\u043e\u0431\u044b \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u043c\u0430\u0433\u0430\u0437\u0438\u043d.", + "remove": "&c&l[\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043c\u0430\u0433\u0430\u0437\u0438\u043d]", + "remove-hover": "&e\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430.", + "commands": { + "setowner": "\/qs setowner [\u0418\u0433\u0440\u043e\u043a]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [\u043d\u043e\u0432\u0430\u044f \u0446\u0435\u043d\u0430]", + "refill": "\/qs refill [\u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a\u2714", + "failed": "&c\u2718" + }, + "tabcomplete": { + "price": "[\u0446\u0435\u043d\u0430]", + "range": "[\u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d]", + "amount": "[\u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e]" + }, + "updatenotify": { + "buttontitle": "[\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0435\u0439\u0447\u0430\u0441]", + "onekeybuttontitle": "[\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u043e\u0434\u0438\u043d \u043a\u043b\u0438\u043a]", + "list": [ + "{0} \u0443\u0436\u0435 \u0432\u044b\u0448\u0435\u043b, \u0412\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 {1}!", + "\u0411\u0443\u043c! \u041d\u043e\u0432\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 {0} \u043d\u0430 \u043f\u043e\u0434\u0445\u043e\u0434\u0435, \u041e\u0431\u043d\u043e\u0432\u0438\u0442\u0435\u0441\u044c!", + "\u0421\u044e\u0440\u043f\u0440\u0438\u0437! {0} \u0443\u0436\u0435 \u0432\u044b\u0448\u0435\u043b, \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 {1}", + "\u0418\u0449\u0438\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435, {0} \u0443\u0436\u0435 \u0437\u0434\u0435\u0441\u044c!", + "\u0423\u0443\u0443\u0443\u0443\u043f\u0441! {0} \u0432\u044b\u0448\u0435\u043b, \u0430 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 {1}!", + "\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 QS {0}, \u043f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f?", + "\u0418\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438 \u043f\u0435\u0440\u0435... \u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435. {0} \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d!", + "\u041e\u0448\u0438\u0431\u043a\u0430! \u041d\u0435\u0442, \u043d\u0435 \u043e\u0448\u0438\u0431\u043a\u0430, \u043f\u0440\u043e\u0441\u0442\u043e {0} \u043e\u0431\u043d\u043e\u0432\u0438\u043b\u0441\u044f!", + "\u041e\u041c\u0413! {0} \u0443\u0436\u0435 \u0432\u044b\u0448\u0435\u043b! \u041f\u043e\u0447\u0435\u043c\u0443 \u0432\u044b \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 {1}?", + "\u041d\u043e\u0432\u043e\u0441\u0442\u044c \u0434\u043b\u044f: \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 QuickShop {0}!", + "\u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f {0}!", + "\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 {0}, \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435!", + "\u0421\u043e\u043e\u0431\u0449\u0438\u0442\u0435 \u0430\u0434\u043c\u0438\u043d\u0443 \u0447\u0442\u043e {0} \u0443\u0436\u0435 \u0432\u044b\u0448\u0435\u043b!", + "\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435---{0} \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d, \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 {1}", + "\u0410\u0445\u0445\u0445\u0445\u0445! \u041d\u043e\u0432\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 {0}! \u041e\u0431\u043d\u043e\u0432\u0438\u0442\u0435\u0441\u044c!", + "\u0427\u0435\u0433\u043e \u0442\u0443\u0442 \u0434\u0443\u043c\u0430\u0442\u044c? {0} \u0432\u044b\u0448\u0435\u043b! \u041e\u0431\u043d\u043e\u0432\u0438\u0442\u0435\u0441\u044c!" + ], + "remote-disable-warning": "&c\u042d\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f QS \u0431\u044b\u043b\u0430 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c, \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0447\u0442\u043e \u0443 \u043d\u0435\u0451 \u0435\u0441\u0442\u044c \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 SpigotMC : {0}. \u042d\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043f\u043e\u043a\u0430 \u0432\u044b \u043d\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u0435 \u043f\u043b\u0430\u0433\u0438\u043d.", + "label": { + "unstable": "[\u041d\u0435 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0439]", + "stable": "[\u0421\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0439]", + "lts": "[LTS]", + "qualityverifyed": "[\u041a\u0430\u0447\u0435\u0441\u0442\u0432\u043e]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0432\u0435\u0442\u043a\u0430]" + } + }, + "shop-removed-cause-ongoing-fee": "&c\u0412\u0430\u0448 \u043c\u0430\u0433\u0430\u0437\u0438\u043d \u043d\u0430 {0} \u0431\u044b\u043b \u0443\u0434\u0430\u043b\u0435\u043d \u0442.\u043a. \u0443 \u0432\u0430\u0441 \u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u0435\u043d\u0435\u0433 \u0447\u0442\u043e\u0431\u044b \u0435\u0433\u043e \u043e\u043f\u043b\u0430\u0447\u0438\u0432\u0430\u0442\u044c!", + "digits-reach-the-limit": "&c\u0414\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442 \u043b\u0438\u043c\u0438\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0446\u0438\u0444\u0440 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u044f\u0442\u043e\u0439.", + "complete": "&a\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e!" +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/tr.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/tr.json new file mode 100644 index 0000000..28a84a4 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/tr.json @@ -0,0 +1,234 @@ +{ + "translation-author": "\u00c7evirmen: DazzGranto", + "translation-version": "Support Version: Reremake", + "translation-contributors": "Katk\u0131da Bulunanlar: Hi\u00e7 Kimse", + "translation-country": "Dil B\u00f6lgesi: T\u00fcrk\u00e7e (tr_TR)", + "language-version": "27", + "not-looking-at-shop": "&cQuickShop bulunamad\u0131, birine bak\u0131yor olmal\u0131s\u0131n.", + "no-anythings-in-your-hand": "&cElinde hi\u00e7bir \u015fey yok.", + "no-permission": "&cBunu yapmaya iznin yok.", + "no-creative-break": "&cYarat\u0131c\u0131 modda di\u011fer oyuncular\u0131n marketlerini k\u0131ramazs\u0131n\u0131z. Bunun yerine hayatta kalma modunu kullan\u0131n.", + "no-double-chests": "&c\u00c7ifte sand\u0131k ile market olu\u015fturamazs\u0131n\u0131z.", + "shop-already-owned": "&cBu zaten bir market.", + "chest-was-removed": "&cSand\u0131k kald\u0131r\u0131ld\u0131.", + "price-too-cheap": "&cFiyat &e${0}&c'dan b\u00fcy\u00fck olmal\u0131d\u0131r.", + "no-price-change": "&cBu bir fiyat de\u011fi\u015fikli\u011fine sebep olmaz.", + "you-cant-afford-a-new-shop": "&cYeni bir market olu\u015fturma maliyeti: ${0}", + "player-bought-from-your-store-tax": "&c{0} purchased {1} {2} from your store, and you paid {3} in taxes.", + "you-cant-afford-to-change-price": "&cMarketinizin fiyat\u0131n\u0131 de\u011fi\u015ftirmek ${0} tutar\u0131ndad\u0131r.", + "success-created-shop": "&aMarket olu\u015fturuldu.", + "success-removed-shop": "&aMarket kald\u0131r\u0131ld\u0131.", + "shops-arent-locked": "&cUnutmay\u0131n! Marketler h\u0131rs\u0131zlara kar\u015f\u0131 koruma alt\u0131nda DE\u011e\u0130LD\u0130R. E\u011fer marketleri korumak istiyorsan\u0131z LWC, Lockette, vb. eklentiler ile kilitleyiniz.", + "shop-creation-cancelled": "&cMarket olu\u015fturma iptal edildi.", + "shop-purchase-cancelled": "&cMarket sat\u0131n alma i\u015flemi iptal edildi.", + "shop-stock-too-low": "&cThe shop only has {0} {1} left", + "you-cant-afford-to-buy": "&cBu ${0}'a m\u00e2l oluyor ama sende ${1} var.", + "negative-amount": "&cSaf! Negatif miktarlarda i\u015flem yapamazs\u0131n.", + "not-a-number": "&cYaln\u0131zca say\u0131 kullanabilirsiniz ama siz {0} girdiniz.", + "not-a-integer": "&cYaln\u0131zca tamsay\u0131 kullanabilirsiniz ama siz {0} girdiniz.", + "player-bought-from-your-store": "&c{0} purchased {1} {2} from your store.", + "shop-out-of-stock": "&5Your shop at {0}, {1}, {2}, has run out of {3}", + "shop-has-no-space": "&cThe shop only has room for {0} more {1}.", + "you-dont-have-that-many-items": "&cYou only have {0} {1}.", + "the-owner-cant-afford-to-buy-from-you": "&cThat costs {0} but the owner only has {1}", + "player-sold-to-your-store": "&a{0} sold {1} {2} to your store.", + "shop-out-of-space": "&5Your shop at {0}, {1}, {2}, is now full.", + "fee-charged-for-price-change": "&aYou pay &c{0}&a to change the price.", + "price-is-now": "&aThe shops new price is &e{0}", + "thats-not-a-number": "&cGe\u00e7ersiz say\u0131", + "no-price-given": "&cL\u00fctfen ge\u00e7erli bir fiyat verin.", + "average-price-nearby": "&aYak\u0131ndaki Ortalama Fiyat: &e${0}", + "shop-has-changed": "&cKullanmaya \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131z market, t\u0131klad\u0131\u011f\u0131n\u0131zdan beri de\u011fi\u015fti.", + "shop-not-exist": "&cOrada market yoktu.", + "nearby-shop-this-way": "&aMarket sizden {0} blok uzakta.", + "no-nearby-shop": "&cYak\u0131nda {0} ile e\u015fle\u015fen market yok.", + "buying-more-than-selling": "&cUYARI: Satt\u0131\u011f\u0131n\u0131zdan fazla \u00fcr\u00fcn sat\u0131n al\u0131yorsunuz.", + "not-enough-space": "&cSadece {0} tane daha yeriniz kald\u0131.", + "refill-success": "&aDoldurma i\u015flemi ba\u015far\u0131l\u0131", + "empty-success": "&aBo\u015faltma i\u015flemi ba\u015far\u0131l\u0131", + "admin-shop": "AdminMarketi", + "unknown-owner": "Bilinmiyor", + "owner-bypass-check": "&eBypassed all checks, Trade successful! (You are shop owner)", + "reached-maximum-can-create": "&cYou have already created a maximum of {0}\/{1} shops!", + "restricted-prices": "&cRestricted prices for {0}: min {1} , max {2}", + "no-enough-money-to-keep-shops": "&cYou didn't have enough money to keep your shops! All shops have now been removed...", + "nothing-to-flush": "&aYou had no new shop message.", + "break-shop-use-supertool": "&eYou can break the shop by using the SuperTool.", + "failed-to-put-sign": "&cNot enough space around the shop to place the information sign.", + "failed-to-paste": "&cFailed to upload the data to Pastebin, Check your internet and try again. (See console for details)", + "warn-to-paste": "&eCollecting data and uploading it to Pastebin, this may take a while. &c&lWarning&c, The data is kept public for one week, it may leak your server configuration and other sensitive information, make sure you only send it to your <rusted staff\/developer.", + "price-too-high": "&c The shop price too high! You can't create one that is priced higher than {0}.", + "you-cant-create-shop-in-there": "&cYou don't have permission to create a shop at this location.", + "unknown-player": "&cTarget player doesn't exist, please check the username you typed.", + "shop-staff-cleared": "&aSuccessfully removed all staff for your shop.", + "shop-staff-added": "&aSuccessfully added {0} to your shop staffs.", + "shop-staff-deleted": "&aSuccessfully removed {0} from your shop staffs.", + "no-permission-build": "&cYou can't build a shop here.", + "success-change-owner-to-server": "&aSuccessfully set the shop owner to Server.", + "flush-finished": "&aSuccessfully flushed the messages.", + "purchase-failed": "&cPurchase failed: Internal Error, please contact the server administrator.", + "no-pending-action": "&cYou do not have any pending action", + "permission-denied-3rd-party": "&cPermission denied: 3rd party plugin [{0}].", + "menu": { + "successful-purchase": "&aSuccessfully Purchased:", + "successfully-sold": "&aSuccessfully Sold:", + "item-name-and-price": "&e{0} {1} &afor &e{2}", + "sell-tax": "&aYou paid &e{0} &ain taxes.", + "sell-tax-self": "&aYou own this shop so you don't pay taxes.", + "enchants": "&5Enchants", + "stored-enchants": "&5Stored Enchants", + "shop-information": "&aShop Information:", + "owner": "&aOwner: {0}", + "item": "&aItem: &e{0}", + "preview": "&b[Preview Item]", + "space": "&aSpace: &e{0}", + "stock": "&aStock &e{0}", + "price-per": "&aPrice per &e{0} &a- &e{1}", + "total-value-of-chest": "&aTotal value of Chest: &e{0}", + "damage-percent-remaining": "&e{0}% &aRemaining.", + "this-shop-is-buying": "&aThis shop is &dBUYING&a items.", + "this-shop-is-selling": "&aThis shop is &bSELLING&a items.", + "effects": "&aEffects", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&cBypassing a QuickShop lock!", + "that-is-locked": "&cThat shop is locked.", + "how-many-buy": "&aEnter how many you wish to &bBUY&a in chat. You can buy &e{0}&a. Enter &ball&a to buy them all.", + "how-many-sell": "&aEnter how many you wish to &dSELL&a in chat. You have &e{0}&a available. Enter &ball&a to sell them all.", + "not-allowed-to-create": "&cYou may not create a shop here.", + "blacklisted-item": "&cThat item is blacklisted. You may not sell it", + "how-much-to-trade-for": "&aEnter how much you wish to trade one &e{0}&a for in chat.", + "command": { + "toggle-unlimited": { + "unlimited": "&aShop is now unlimited", + "limited": "&aShop is now limited" + }, + "no-owner-given": "&cNo owner given. Use &a\/qs setowner &c", + "new-owner": "&aNew owner: &e{0}", + "now-buying": "&aNow &dBUYING&a &e{0}", + "now-selling": "&aNow &bSELLING &e{0}", + "cleaning": "&aCleaning up shops with 0 stock...", + "reloading": "&aReloading...", + "cleaned": "&aCleaned &e{0}&a shops", + "no-type-given": "&cUsage: \/qs find ", + "no-amount-given": "&cNo amount given. Use &a\/qs refill &c", + "now-debuging": "&aSuccessfully switched to developer mode, Reloading QuickShop...", + "now-nolonger-debuging": "&aSuccessfully switched to production mode, Reloading QuickShop...", + "wrong-args": "&cParameters don't match, use \/qs help to check help", + "description": { + "title": "&aQuickShop Help", + "unlimited": "&eMakes a shop unlimited", + "setowner": "&eChanges who owns a shop", + "owner": "&eChanges who owns a shop", + "buy": "&eConverts a shop to &dBUY&e mode", + "sell": "&eConverts a shop to &bSELL&e mode", + "price": "&eChanges the buy\/selling price of one of your shops", + "clean": "&eRemoves all (loaded) shops with 0 stock", + "find": "&eLocates the nearest shop of a specific type.", + "reload": "&eReloads the config.yml for QuickShop", + "refill": "&eAdds a given number of items to a shop", + "empty": "&eRemoves all stock from a shop", + "debug": "&eSwitch to developer mode", + "create": "&eCreates a new shop at the target chest", + "fetchmessage": "&eFetch unread shop message", + "info": "&eShow QuickShop Statistics", + "paste": "&eAuto upload server data to Pastebin", + "staff": "&eManage your shop staffs", + "remove": "&eRemove your looking the shop", + "amount": "&eExecute for your actions with amount(For chat plugin issue)", + "about": "&eShow QuickShop abouts", + "help": "&eShow QuickShop helps", + "supercreate": "&eCreate a shop bypass all protection checks" + } + }, + "signs": { + "selling": "Selling {0}", + "header": "&c{0}", + "buying": "Buying {0}", + "item": "{0}", + "price": "{0} each", + "unlimited": "Unlimited" + }, + "controlpanel": { + "setowner": "&aOwner: &b{0} &e[&d&lChange&e]", + "infomation": "&aShop Control Panel:", + "setowner-hover": "&eClick to switch owner.", + "unlimited": "&aUnlimited: {0} &e[&d&lSwitch&e]", + "unlimited-hover": "&eClick to toggle if the shop is unlimited.", + "mode-selling": "&aShop mode: &bSelling &e[&d&lSwitch&e]", + "mode-selling-hover": "&eClick to convert the shop to be in the buying mode.", + "mode-buying": "&aShop mode: &bBuying &e[&d&lSwitch&e]", + "mode-buying-hover": "&eClick to convert the shop to be in the selling mode.", + "price": "&aPrice: &b{0} &e[&d&lSet&e]", + "price-hover": "&eClick to set a new price for the shop.", + "refill": "&aRefill: Refill the shop items &e[&d&lOK&e]", + "refill-hover": "&eClick to refill the shop.", + "empty": "&aEmpty: Remove shop all items &e[&d&lOK&e]", + "empty-hover": "&eClick to clear the inventory of the shop.", + "remove": "&c&l[Remove Shop]", + "remove-hover": "&eClick to remove this shop.", + "commands": { + "setowner": "\/qs setowner [Player]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [New Price]", + "refill": "\/qs refill [Amount]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a\u2714", + "failed": "&c\u2718" + }, + "tabcomplete": { + "price": "[price]", + "range": "[range]", + "amount": "[amount]" + }, + "updatenotify": { + "buttontitle": "[Update Now]", + "onekeybuttontitle": "[OneKey Update]", + "list": [ + "{0} is released, You are still using {1}!", + "Boom! New update {0} incoming, Update!", + "Surprise! {0} came out, you are on {1}", + "Looks like you need to update, {0} is released!", + "Ooops! {0} is now released, you are on {1}!", + "I promise, QS has been updated to {0}, why have you not updated?", + "Fixing and re... Sorry {0} is released!", + "Err! Nope, this is not an error, {0} has just been released!", + "OMG! {0} came out! Why are you still using {1}?", + "Todays News: QuickShop has been updated to {0}!", + "Plugin K.I.A, You should update to {0}!", + "Fuze is fuzeing update {0}, save update!", + "There is an update commander, {0} has just come out!", + "Look me style---{0} updated, your still using {1}", + "Ahhhhhhh! New update {0}! Update!", + "What U thinking? {0} has been released! Update!" + ], + "remote-disable-warning": "&cThis version of QuickShop is marked disabled by remote server, that mean this version may have serious problem, get details from our SpigotMC page: {0}. This warning will appear and spam your console until you use other not disabled version to replace this one, doesn't effect your server running.", + "label": { + "unstable": "[Unstable]", + "stable": "[Stable]", + "lts": "[LTS]", + "qualityverifyed": "[Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&cYou shop at {0} was removed cause you had no enough money to keep it!", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&aComplete!" +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/zh-CN.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/zh-CN.json new file mode 100644 index 0000000..4c79559 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/zh-CN.json @@ -0,0 +1,234 @@ +{ + "translation-author": "\u7ffb\u8bd1\u8005\uff1a&b&lMashirl happyvalley yzhh You_wen", + "translation-version": "\u652f\u6301\u7248\u672c\uff1aReremake", + "translation-contributors": "\u5f00\u53d1\u8d21\u732e\u8005\uff1aTimtower, Netherfoam, KaiNoMood and Mgazul", + "translation-country": "\u672c\u5730\u5316\u8bed\u8a00\uff1a\u7b80\u4f53\u4e2d\u6587 (zh_CN)", + "language-version": "27", + "not-looking-at-shop": "&c\u6ca1\u6709\u627e\u5230\u5546\u5e97, \u4f60\u5fc5\u987b\u9009\u4e2d\u7bb1\u5b50\u624d\u884c\u3002", + "no-anythings-in-your-hand": "&c\u4f60\u7684\u624b\u91cc\u6ca1\u6709\u4efb\u4f55\u7269\u54c1\u3002", + "no-permission": "&c\u4f60\u6ca1\u6709\u6743\u9650\u8fd9\u6837\u505a\u3002", + "no-creative-break": "&c\u4f60\u4e0d\u80fd\u5728\u521b\u9020\u6a21\u5f0f\u7834\u574f\u5176\u5b83\u73a9\u5bb6\u7684\u5546\u5e97\uff0c\u8bf7\u4f7f\u7528\u751f\u5b58\u6a21\u5f0f\u3002", + "no-double-chests": "&c\u4f60\u6ca1\u6709\u6743\u9650\u521b\u5efa\u5927\u7bb1\u5b50\u5546\u5e97\u3002", + "shop-already-owned": "&c\u8fd9\u5df2\u7ecf\u662f\u4e00\u4e2a\u5546\u5e97\u4e86\u3002", + "chest-was-removed": "&c\u5f53\u524d\u7bb1\u5b50\u5df2\u88ab\u79fb\u9664\u3002", + "price-too-cheap": "&c\u4ef7\u683c\u5fc5\u987b\u5927\u4e8e&e${0}", + "no-price-change": "&c\u8fd9\u4e0d\u4f1a\u5bfc\u81f4\u4ef7\u683c\u53d8\u52a8\uff01", + "you-cant-afford-a-new-shop": "&\u4f60\u9700\u8981 {0} \u624d\u80fd\u521b\u5efa\u4e00\u4e2a\u5546\u5e97\u3002", + "player-bought-from-your-store-tax": "&c{0} \u4ece\u4f60\u7684\u5546\u5e97\u8d2d\u4e70\u4e86 {1} {2}\uff0c\u4ea4\u7eb3\u4e86{3}\u7684\u7a0e\u3002", + "you-cant-afford-to-change-price": "&c\u4f60\u9700\u8981 {0} \u624d\u80fd\u4fee\u6539\u5546\u5e97\u7684\u4ef7\u683c\u3002", + "success-created-shop": "&a\u521b\u5efa\u5546\u5e97\u6210\u529f\uff01", + "success-removed-shop": "&a\u5546\u5e97\u5df2\u5220\u9664\uff01", + "shops-arent-locked": "&c\u6ce8\u610f\uff0c\u5546\u5e97\u65e0\u6cd5\u9632\u76d7\uff0c\u5982\u679c\u60a8\u60f3\u8981\u9632\u76d7\u529f\u80fd\uff0c\u8bf7\u4f7f\u7528Lockette\uff0cLWC\uff0c\u7b49\u63d2\u4ef6\u9501\u4f4f\u7bb1\u5b50\u3002", + "shop-creation-cancelled": "&c\u5df2\u53d6\u6d88\u521b\u5efa\u5546\u5e97\u3002", + "shop-purchase-cancelled": "&c\u5df2\u53d6\u6d88\u8d2d\u4e70\u3002", + "shop-stock-too-low": "&c\u8fd9\u4e2a\u5546\u5e97\u53ea\u6709 {0} \u4e2a {1} \u4e86\u3002", + "you-cant-afford-to-buy": "&c\u4f59\u989d\u4e0d\u8db3\uff01\u8d2d\u4e70\u8be5\u5546\u5e97\u7269\u54c1\u9700\u8981 {0}\uff0c\u4f46\u662f\u4f60\u53ea\u6709 {1}\u3002", + "negative-amount": "'&c\u4f60\u662f\u4e0d\u662f\u6253\u9519\u4e86\uff1f\u8fd9\u4e2a\u4ea4\u6613\u65e0\u6cd5\u751f\u6548\u3002", + "not-a-number": "&c\u8fd9\u91cc\u53ea\u80fd\u8f93\u5165\u6570\u5b57\uff0c\u4f46\u662f\u60a8\u8f93\u5165\u7684\u662f {0}", + "not-a-integer": "&c\u8fd9\u91cc\u53ea\u80fd\u8f93\u5165\u6570\u5b57\uff0c\u4f46\u662f\u60a8\u8f93\u5165\u7684\u662f {0}", + "player-bought-from-your-store": "&c{0} \u5728\u4f60\u7684\u5546\u5e97\u8d2d\u4e70\u4e86 {1} \u4e2a {2} \u3002", + "shop-out-of-stock": "&5\u4f60\u4f4d\u4e8e {0}, {1}, {2},\u7684\u5546\u5e97\u7684 {3} \u5e93\u5b58\u5df2\u7ecf\u6ca1\u6709\u4e86\u3002", + "shop-has-no-space": "&c\u8fd9\u4e2a\u5546\u5e97\u53ea\u80fd\u88c5\u4e0b {0} \u4e2a {1} \u4e86\u3002", + "you-dont-have-that-many-items": "&c\u4f60\u53ea\u6709 {0} \u4e2a {1}\u3002", + "the-owner-cant-afford-to-buy-from-you": "&c\u8fd9\u4ef6\u5546\u54c1\u6807\u4ef7 {0}\uff0c\u4f46\u662f\u5e97\u4e3b\u53ea\u5269 {1} \u4e86\u3002", + "player-sold-to-your-store": "&a{0} \u5728\u4f60\u7684\u5546\u5e97\u51fa\u552e\u4e86 {1} \u4e2a {2} \u3002", + "shop-out-of-space": "&5\u4f60\u4f4d\u4e8e {0}, {1}, {2},\u7684\u5546\u5e97\u5e93\u5b58\u7206\u4ed3\u4e86\u3002", + "fee-charged-for-price-change": "&a\u4f60\u82b1\u4e86 &c{0}&a \u4fee\u6539\u4e86\u4ef7\u683c\u3002", + "price-is-now": "&a\u65b0\u4ef7\u683c\u662f &e{0} \u3002", + "thats-not-a-number": "&c\u65e0\u6548\u6570\u5b57\u3002", + "no-price-given": "&c\u8bf7\u8f93\u5165\u4e00\u4e2a\u6709\u6548\u7684\u4ef7\u683c\u3002", + "average-price-nearby": "&a\u9644\u8fd1\u5e73\u5747\u4ef7\u683c: &e{0}", + "shop-has-changed": "&c\u5546\u5e97\u5728\u4f60\u5c1d\u8bd5\u4f7f\u7528\u7684\u65f6\u5019\u53d1\u751f\u4e86\u66f4\u6539\u4ece\u4f60\u70b9\u51fb\u4ed6\u7684\u65f6\u5019\u8d77", + "shop-not-exist": "&c\u8fd9\u91cc\u6ca1\u6709\u5546\u5e97", + "nearby-shop-this-way": "&a\u5546\u5e97\u8ddd\u79bb\u4f60 {0} \u683c\u8fdc", + "no-nearby-shop": "&c\u5468\u56f4\u6ca1\u6709\u4e0e {0} \u5339\u914d\u7684\u5546\u5e97", + "buying-more-than-selling": "&c\u8b66\u544a:\u4f60\u4e70\u7684\u4e1c\u897f\u6bd4\u4f60\u5356\u7684\u591a!", + "not-enough-space": "&c\u6b64\u5546\u5e97\u7a7a\u95f4\u4e0d\u8db3\uff0c\u5269\u4f59 {0}", + "refill-success": "&a\u91cd\u586b\u6210\u529f", + "empty-success": "&a\u6e05\u7a7a\u6210\u529f", + "admin-shop": "\u7cfb\u7edf\u5546\u5e97", + "unknown-owner": "\u672a\u77e5", + "owner-bypass-check": "&e\u7ed5\u8fc7\u6240\u6709\u68c0\u67e5\uff0c\u4ea4\u6613\u5df2\u5b8c\u6210\uff08\u4f60\u662f\u5546\u5e97\u6240\u6709\u8005\uff09", + "reached-maximum-can-create": "&c\u4f60\u521b\u5efa\u7684\u5546\u5e97\u6570\u91cf\u8fbe\u5230\u4e0a\u9650{0}\/{1}", + "restricted-prices": "&c\u7269\u54c1{0}\u4ef7\u683c\u6536\u5230\u9650\u5236\uff1a\u6700\u5c0f {1}\uff0c\u6700\u5927{2}", + "no-enough-money-to-keep-shops": "&c\u4f60\u6ca1\u6709\u8db3\u591f\u7684\u91d1\u94b1\u53bb\u7ef4\u6301\u4f60\u7684\u5546\u5e97\uff01\u6240\u6709\u5546\u5e97\u5df2\u88ab\u79fb\u9664...", + "nothing-to-flush": "&a\u4f60\u6ca1\u6709\u65b0\u7684\u5546\u5e97\u6d88\u606f", + "break-shop-use-supertool": "&e\u4f60\u53ef\u4ee5\u4f7f\u7528SuperTool\u6765\u7834\u574f\u5546\u5e97", + "failed-to-put-sign": "&c\u5546\u5e97\u6ca1\u6709\u8db3\u591f\u7684\u7a7a\u95f4\u653e\u7f6e\u4fe1\u606f\u724c\u3002", + "failed-to-paste": "&c\u6570\u636e\u4e0a\u4f20\u5230Pastebin\u5931\u8d25\uff0c\u68c0\u67e5\u4f60\u7684\u7f51\u7edc\u5e76\u91cd\u8bd5\u3002\uff08\u67e5\u770b\u540e\u53f0\u83b7\u53d6\u8be6\u60c5\uff09", + "warn-to-paste": "&e\u6536\u96c6\u5e76\u4e0a\u4f20\u6570\u636e\u5230Pastebin\uff0c\u8fd9\u4f1a\u82b1\u8d39\u70b9\u65f6\u95f4\u3002&c&l\u8b66\u544a&c\uff0c\u6570\u636e\u5c06\u4f1a\u5728\u4e00\u5468\u5185\u5bf9\u5916\u53ef\u89c1\uff0c\u53ef\u80fd\u4f1a\u5bfc\u81f4\u4f60\u6cc4\u9732\u670d\u52a1\u5668\u7684\u914d\u7f6e\u548c\u5176\u4ed6\u654f\u611f\u4fe1\u606f\uff0c\u786e\u4fdd\u53ea\u5411&l\u4f60\u4fe1\u4efb\u7684\u4eba\/\u5f00\u53d1\u8005&c\u53d1\u9001\u94fe\u63a5\u3002", + "price-too-high": "&c\u5546\u54c1\u7684\u4ef7\u683c\u592a\u9ad8\u4e86\uff01\u4f60\u4e0d\u80fd\u521b\u5efa\u9ad8\u4e8e {0} \u7684\u5546\u5e97\u3002", + "you-cant-create-shop-in-there": "&c\u4f60\u6ca1\u6709\u5728\u8fd9\u4e2a\u4f4d\u7f6e\u521b\u5efa\u5546\u5e97\u7684\u6743\u9650\u3002", + "unknown-player": "&c\u76ee\u6807\u73a9\u5bb6\u4e0d\u5b58\u5728\uff0c\u8bf7\u68c0\u67e5\u4f60\u8f93\u5165\u7684\u73a9\u5bb6\u540d\u5b57\u3002", + "shop-staff-cleared": "&a\u6210\u529f\u4ece\u4f60\u7684\u5546\u5e97\u79fb\u9664\u6240\u6709\u52a9\u624b\u4efb\u610f", + "shop-staff-added": "&a\u6210\u529f\u6dfb\u52a0 {0} \u5230\u4f60\u7684\u5546\u5e97\u7684\u52a9\u624b\u4e2d", + "shop-staff-deleted": "&a\u6210\u529f\u4ece\u4f60\u7684\u5546\u5e97\u7684\u52a9\u624b\u4e2d\u79fb\u9664 {0}", + "no-permission-build": "&c\u4f60\u4e0d\u80fd\u5728\u8fd9\u91cc\u5efa\u7acb\u5546\u5e97\u3002", + "success-change-owner-to-server": "&a\u6210\u529f\u8bbe\u7f6e\u5546\u5e97\u6240\u6709\u8005\u4e3a \u670d\u52a1\u5668", + "flush-finished": "&a\u6210\u529f\u83b7\u53d6\u6240\u6709\u5546\u5e97\u8bb0\u5f55", + "purchase-failed": "&c\u652f\u4ed8\u5931\u8d25\uff1a\u5185\u90e8\u9519\u8bef\uff0c\u8bf7\u8054\u7cfb\u670d\u52a1\u5668\u7ba1\u7406\u5458", + "no-pending-action": "&c\u4f60\u6ca1\u6709\u4efb\u4f55\u8fdb\u884c\u4e2d\u7684\u64cd\u4f5c", + "permission-denied-3rd-party": "&c\u6ca1\u6709\u6743\u9650\uff1a\u7b2c\u4e09\u65b9\u63d2\u4ef6 [{0}]\u3002", + "menu": { + "successful-purchase": "&a\u6210\u529f\u652f\u4ed8\uff1a", + "successfully-sold": "&a\u6210\u529f\u51fa\u552e\uff1a", + "item-name-and-price": "&e{0} {1} &a\u6bcf &e{2}", + "sell-tax": "&a\u4f60\u652f\u4ed8\u4e86&e{0}&a\u7684\u7a0e\u3002", + "sell-tax-self": "&a\u4f60\u662f\u8fd9\u4e2a\u5546\u5e97\u7684\u4e3b\u4eba\u6240\u4ee5\u4e0d\u7528\u4ea4\u7a0e\u3002", + "enchants": "&5\u9644\u9b54", + "stored-enchants": "&5\u9644\u9b54", + "shop-information": "&a\u5546\u5e97\u4fe1\u606f\uff1a", + "owner": "&a\u6240\u6709\u8005\uff1a{0}", + "item": "&a\u7269\u54c1\uff1a&e{0}", + "preview": "&b[\u7269\u54c1\u9884\u89c8]", + "space": "&a\u7a7a\u95f4: &e{0}", + "stock": "&a\u5e93\u5b58&e{0}", + "price-per": "&a\u6bcf&e{0}&a\u4ef7\u683c&e{1}", + "total-value-of-chest": "&a\u5171\u8ba1\u5546\u5e97\u6570: &e{0}", + "damage-percent-remaining": "&e{0}% &a\u5269\u4f59", + "this-shop-is-buying": "&a\u8fd9\u4e2a\u5546\u5e97&d\u6536\u8d2d&a\u7269\u54c1\u3002", + "this-shop-is-selling": "&a\u8fd9\u4e2a\u5546\u5e97&d\u51fa\u552e&a\u7269\u54c1\u3002", + "effects": "&a\u6548\u679c", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&c\u4f60\u7ed5\u8fc7\u4e86QuickShop\u7684\u9501\uff01", + "that-is-locked": "&c\u8fd9\u4e2a\u5546\u5e97\u5df2\u4e0a\u9501\u3002", + "how-many-buy": "&a\u5728\u804a\u5929\u680f\u4e2d\u8f93\u5165\u60f3 &b\u8d2d\u4e70 &a\u7684\u6570\u91cf", + "how-many-sell": "&a\u5728\u804a\u5929\u680f\u4e2d\u8f93\u5165\u60f3 &d\u51fa\u552e &a\u7684\u6570\u91cf. \u4f60\u6709\u8fd8\u6709 &e{0} &a\u7269\u54c1", + "not-allowed-to-create": "&c\u4f60\u4e0d\u80fd\u5728\u8fd9\u91cc\u521b\u5efa\u5546\u5e97", + "blacklisted-item": "&c\u6b64\u7269\u54c1\u4f4d\u4e8e\u9ed1\u540d\u5355\u4e2d\uff0c\u4f60\u4e0d\u53ef\u4ee5\u51fa\u552e\u5b83", + "how-much-to-trade-for": "&a\u8f93\u5165\u6bcf\u4e2a &e{0} &a\u7684\u4ef7\u683c", + "command": { + "toggle-unlimited": { + "unlimited": "&a\u5546\u5e97\u73b0\u5728\u662f\u65e0\u9650\u7684\u3002", + "limited": "&a\u5546\u5e97\u73b0\u5728\u662f\u6709\u9650\u7684\u3002" + }, + "no-owner-given": "&c\u672a\u6307\u5b9a\u65b0\u7684\u6240\u6709\u8005. \u4f7f\u7528 &a\/qs owner <\u65b0\u7684\u5e97\u4e3b>&c", + "new-owner": "&a\u65b0\u7684\u5546\u5e97\u6240\u6709\u8005: &e{0}", + "now-buying": "&a\u73b0\u5728 &d\u6536\u8d2d\u4e2d &e{0}", + "now-selling": "&a\u73b0\u5728 &b\u51fa\u552e\u4e2d &e{0}", + "cleaning": "&c\u6b63\u5728\u6e05\u7406\u8131\u9500\u5546\u5e97...", + "reloading": "&a\u91cd\u8f7d\u4e2d", + "cleaned": "&a\u6e05\u7406\u4e86 &e{0} &a\u4e2a\u5546\u5e97", + "no-type-given": "&c\u7528\u6cd5: \/qs find <\u7269\u54c1\u540d\u79f0>", + "no-amount-given": "&c\u6570\u91cf\u672a\u6307\u5b9a. \u4f7f\u7528 &a\/qs refull <\u6570\u91cf>&c", + "now-debuging": "&a\u6210\u529f\u5207\u6362\u5230\u4e86\u5f00\u53d1\u8005\u6a21\u5f0f\uff0c\u63d2\u4ef6\u91cd\u8f7d\u4e2d...", + "now-nolonger-debuging": "&a\u6210\u529f\u5207\u6362\u5230\u4e86\u751f\u4ea7\u73af\u5883\u6a21\u5f0f\uff0c\u63d2\u4ef6\u91cd\u8f7d\u4e2d...", + "wrong-args": "&c\u53c2\u6570\u4e0d\u5339\u914d\uff0c\u4f7f\u7528\/qs help\u6765\u67e5\u770b\u5e2e\u52a9", + "description": { + "title": "&aQuickShop \u5e2e\u52a9", + "unlimited": "&e\u5207\u6362\u5546\u5e97\u5230\u65e0\u9650\u6a21\u5f0f", + "setowner": "&e\u4e3a\u5546\u5e97\u8bbe\u7f6e\u65b0\u7684\u6240\u6709\u8005\u3002", + "owner": "&e\u4e3a\u5546\u5e97\u8bbe\u7f6e\u65b0\u5e97\u4e3b", + "buy": "&e\u5207\u6362\u5230 &d\u6536\u8d2d &e\u6a21\u5f0f", + "sell": "&e\u5207\u6362\u5230 &b\u51fa\u552e &e\u6a21\u5f0f", + "price": "&e\u4fee\u6539 \u6536\u8d2d\/\u51fa\u552e \u7684\u4ef7\u683c", + "clean": "&e\u79fb\u9664\u6240\u6709\u5df2\u52a0\u8f7d\u7684\u8131\u9500\u7684\u5546\u5e97", + "find": "&e\u5bfb\u627e\u9644\u8fd1\u5339\u914d\u4f60\u7684\u7269\u54c1\u540d\u79f0\u7684\u5546\u5e97", + "reload": "&e\u4e3a QuickShop \u91cd\u8f7d config.yml", + "refill": "&e\u6dfb\u52a0\u4e00\u5b9a\u6570\u91cf\u7684\u7269\u54c1\u5230\u5546\u5e97", + "empty": "&e\u6e05\u7a7a\u5546\u5e97\u5e93\u5b58", + "debug": "&e\u5207\u6362\u5230\u5f00\u53d1\u8005\u6a21\u5f0f", + "create": "&e\u5c06\u76ee\u6807\u7bb1\u5b50\u8bbe\u7f6e\u4e3a\u5546\u5e97", + "fetchmessage": "&e\u83b7\u53d6\u672a\u8bfb\u5546\u5e97\u65e5\u5fd7", + "info": "&e\u67e5\u770bQuickShop\u7edf\u8ba1\u4fe1\u606f", + "paste": "&e\u4e0a\u4f20\u8c03\u8bd5\u4fe1\u606f\u5230Patebin", + "staff": "&e\u7ba1\u7406\u5546\u5e97\u52a9\u624b", + "remove": "&e\u79fb\u9664\u4f60\u9009\u4e2d\u7684\u7684\u5546\u5e97", + "amount": "&e\u4ee5\u6307\u5b9a\u6570\u91cf\u6267\u884c\u4f60\u8fdb\u884c\u4e2d\u7684\u64cd\u4f5c(\u7528\u4e8e\u89e3\u51b3\u804a\u5929\u63d2\u4ef6\u5e26\u6765\u7684\u4e0d\u517c\u5bb9\u95ee\u9898)", + "about": "&e\u5173\u4e8eQuickShop", + "help": "&e\u663e\u793aQuickShop\u5e2e\u52a9", + "supercreate": "&e\u8d8a\u8fc7\u6240\u6709\u533a\u57df\u4fdd\u62a4\u68c0\u67e5\u521b\u5efa\u5546\u5e97" + } + }, + "signs": { + "selling": "\u51fa\u552e {0}", + "header": "&c{0}", + "buying": "\u6536\u8d2d {0}", + "item": "{0}", + "price": "\u5355\u4ef7\uff1a{0}", + "unlimited": "\u65e0\u9650" + }, + "controlpanel": { + "setowner": "&a\u6240\u6709\u8005: &b{0} &e[&d&l\u4fee\u6539&e]", + "infomation": "&a\u5546\u5e97\u63a7\u5236\u9762\u677f", + "setowner-hover": "&e\u70b9\u51fb\u6765\u4fee\u6539\u5e97\u4e3b", + "unlimited": "&a\u65e0\u9650\u6a21\u5f0f: {0} &e[&d&l\u5207\u6362&e]", + "unlimited-hover": "&e\u70b9\u51fb\u5207\u6362\u5546\u5e97\u662f\u5426\u4e3a\u65e0\u9650\u6a21\u5f0f", + "mode-selling": "&a\u5546\u5e97\u6a21\u5f0f: &b\u51fa\u552e &e[&d&l\u5f00\u5173&e]", + "mode-selling-hover": "&e\u70b9\u51fb\u66f4\u6362\u9500\u552e\u6a21\u5f0f\u3002", + "mode-buying": "&a\u5546\u5e97\u6a21\u5f0f: &b\u6536\u8d2d &e[&d&l\u66f4\u6539&e]", + "mode-buying-hover": "&e\u70b9\u51fb\u66f4\u6362\u9500\u552e\u6a21\u5f0f\u3002", + "price": "&a\u4ef7\u683c: &b{0} &e[&d&l\u8bbe\u5b9a&e]", + "price-hover": "&e\u70b9\u51fb\u6765\u7ed9\u5546\u5e97\u8bbe\u7f6e\u4e00\u4e2a\u65b0\u7684\u4ef7\u683c", + "refill": "&a\u586b\u5145: \u91cd\u65b0\u586b\u5145\u5546\u54c1 &e[&d&l\u786e\u8ba4&e]", + "refill-hover": "&e\u70b9\u51fb\u91cd\u65b0\u586b\u5145\u5546\u54c1", + "empty": "&a\u6e05\u7a7a: \u5220\u9664\u5546\u5e97\u6240\u6709\u5546\u54c1 &e[&d&l\u786e\u8ba4&e]", + "empty-hover": "&e\u70b9\u51fb\u6e05\u9664\u5546\u5e97\u5e93\u5b58", + "remove": "&c&l[\u5220\u9664\u5546\u5e97]", + "remove-hover": "&e\u70b9\u51fb\u6765\u5220\u9664\u5546\u5e97", + "commands": { + "setowner": "\/qs setowner [\u73a9\u5bb6id]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [\u4fee\u6539\u540e\u7684\u65b0\u4ef7\u683c]", + "refill": "\/qs refill [\u8865\u8d27\u6570\u91cf]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a\u2714", + "failed": "&c\u2718" + }, + "tabcomplete": { + "price": "[\u4ef7\u683c]", + "range": "[\u8303\u56f4]", + "amount": "[\u6570\u91cf]" + }, + "updatenotify": { + "buttontitle": "[\u7acb\u5373\u66f4\u65b0]", + "onekeybuttontitle": "[\u4e00\u952e\u5347\u7ea7]", + "list": [ + "{0} \u7248\u672c\u5df2\u7ecf\u53d1\u5e03\uff0c\u60a8\u8fd8\u5728\u4f7f\u7528{1}", + "\u5654\u5654\u549a\uff01\u65b0\u7248\u672c{0} \u5df2\u7ecf\u53d1\u5e03\uff0c\u5feb\u5347\u7ea7!", + "\u5728\uff1f{0} \u6765\u4e86\uff0c\u4f60\u8fd8\u5728\u4f7f\u7528{1}", + "\u770b\u8d77\u6765\u4f60\u9700\u8981\u66f4\u65b0\u4e86\uff0c{0} \u7248\u672c\u5df2\u7ecf\u53d1\u5e03\u4e86\uff01", + "\u5662\uff01{0}\u5df2\u7ecf\u53d1\u5e03\u4e86\u5440,\u4f60\u8fd8\u5728\u7528 {1}!", + "\u6211\u4fdd\u8bc1\uff0cQS\u5df2\u7ecf\u5347\u7ea7\u5230\u4e86 {0},\u4f60\u4e3a\u4ec0\u4e48\u6ca1\u6709\u5347\u7ea7\uff1f", + "\u4fee\u590d\u5e76\u66f4\u65b0\u4e86...\u62b1\u6b49\u5176\u5b9e\u662f{0}\u7248\u672c\u5df2\u7ecf\u53d1\u5e03\uff01", + "\u9519\u8bef\uff01\u5176\u5b9e\u5e76\u6ca1\u6709\u9519\u8bef\uff0c\u53ea\u662f {0} \u7248\u672c\u5df2\u7ecf\u53d1\u5e03\u4e86\uff01", + "\u54e6\u4e70\u5676\uff01{0}\u5df2\u7ecf\u51fa\u4e86\u5440\uff01\u4f60\u4e3a\u4ec0\u4e48\u8fd8\u5728\u7528 {1}?", + "\u4eca\u65e5\u65b0\u95fb\uff1aQuickShop\u5df2\u7ecf\u66f4\u65b0\u81f3 {0} \uff01", + "\u63d2\u4ef6\u786e\u8ba4\u5df2\u9635\u4ea1\uff0c\u4f60\u73b0\u5728\u5e94\u8be5\u5347\u7ea7\u63d2\u4ef6\u5230 {0} \uff01", + "\u8fdb\u653b\u65b9\u6b63\u5728\u8fdb\u653b\u66f4\u65b0 {0}\uff0c\u6551\u6551\u66f4\u65b0\u5427\uff01", + "\u8fd9\u91cc\u662f\u5347\u7ea7\u6307\u6325\u5b98\uff0c{0}\u7248\u672c\u521a\u521a\u53d1\u5e03\u4e86\uff01", + "\u770b\u6211\u7684Style\u2192{0} \u51fa\u4e86, \u4f60\u4e3a\u4ec0\u4e48\u8fd8\u5728\u7528 {1}\u5462\uff1f", + "\u554a\u554a\u554a\u554a\u554a\u554a\u554a\u554a\u554a\u554a\uff01\u66f4\u65b0 {0} \u6765\u4e86\uff01\u5feb\u5347\u7ea7\uff01", + "\u4f60\u5728\u60f3\u4ec0\u4e48\u5462\uff1f{0}\u5df2\u7ecf\u53d1\u5e03\u4e86\uff01\u5feb\u66f4\u65b0\uff01" + ], + "remote-disable-warning": "&c\u8fd9\u4e2a\u7248\u672c\u7684QuickShop\u5df2\u7ecf\u88ab\u8fdc\u7a0b\u670d\u52a1\u5668\u505c\u7528\u4e86,\u8fd9\u610f\u5473\u7740\u8fd9\u4e2a\u7248\u672c\u7684QS\u53ef\u80fd\u5b58\u5728\u7740\u4e25\u91cd\u7684\u95ee\u9898\uff0c\u8bf7\u5728\u6211\u4eec\u7684SpigotMC\u63d2\u4ef6\u9875\u9762:{0}\u91cc\u5bfb\u627e\u8be6\u7ec6\u4fe1\u606f\u3002\u8fd9\u4e2a\u8b66\u544a\u4f1a\u51fa\u73b0\u6309\u5e76\u4e14\u5728\u4f60\u7684\u63a7\u5236\u53f0\u4e0a\u901a\u77e5\u76f4\u5230\u4f60\u4f7f\u7528\u5176\u4ed6\u6ca1\u6709\u88ab\u505c\u7528\u7684\u7248\u672c\u6765\u66ff\u6362\u8fd9\u4e2a\u7248\u672c\uff0c\u505c\u7528\u540e\u4e0d\u5f71\u54cd\u60a8\u7684\u670d\u52a1\u5668\u7684\u6b63\u5e38\u8fd0\u884c\u3002", + "label": { + "unstable": "[\u4e0d\u7a33\u5b9a]", + "stable": "[\u7a33\u5b9a]", + "lts": "[\u957f\u671f\u670d\u52a1]", + "qualityverifyed": "[\u8d28\u91cf]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[\u5927\u5e08]" + } + }, + "shop-removed-cause-ongoing-fee": "&c\u4f60\u5728 {0} \u7684\u5546\u5e97\u5df2\u7ecf\u88ab\u79fb\u9664\u4e86\uff0c\u56e0\u4e3a\u4f60\u6ca1\u6709\u8db3\u591f\u7684\u8d44\u91d1\u53bb\u7ef4\u6301\u5b83\uff01", + "digits-reach-the-limit": "&c\u4f60\u8f93\u5165\u7684\u4ef7\u683c\u5c0f\u6570\u70b9\u540e\u9762\u7684\u6570\u5b57\u5df2\u7ecf\u8fbe\u5230\u4e86\u6781\u9650\u3002", + "complete": "&a\u5b8c\u6210\uff01" +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/zh-TW.json b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/zh-TW.json new file mode 100644 index 0000000..c015df4 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/messages/zh-TW.json @@ -0,0 +1,234 @@ +{ + "translation-author": "\u8b6f\u5e2b: &b&lmoontai0724 & Tsuna & \u97f3\u6a02", + "translation-version": "\u652f\u63f4\u7248\u672c: Reremake", + "translation-contributors": "\u5354\u4f5c\u8005: Timtower, Netherfoam, KaiNoMood, Mgazul \u548cAndre_601", + "translation-country": "\u8a9e\u8a00: &b&l\u7e41\u9ad4\u4e2d\u6587 Chinese Traditional (zh_TW)", + "language-version": "27", + "not-looking-at-shop": "&c\u6c92\u6709\u627e\u5230\u5546\u5e97, \u60a8\u5fc5\u9808\u770b\u8457\u4e00\u500b\u5546\u5e97!", + "no-anythings-in-your-hand": "&c\u60a8\u7684\u624b\u4e2d\u662f\u7a7a\u7684\u3002", + "no-permission": "&c\u60a8\u6c92\u6709\u6b0a\u9650\u57f7\u884c\u9019\u500b\u6307\u4ee4\u3002", + "no-creative-break": "&c\u60a8\u4e0d\u80fd\u7528\u5275\u9020\u6a21\u5f0f\u7834\u58de\u4ed6\u4eba\u7684\u5546\u5e97, \u8acb\u5148\u5207\u63db\u70ba\u751f\u5b58\u6a21\u5f0f\u3002", + "no-double-chests": "&c\u60a8\u7121\u6cd5\u5275\u5efa\u4e00\u500b\u5927\u7bb1\u5b50\u5546\u5e97 (\u5169\u500b\u7bb1\u5b50\u7d44\u6210\u7684\u5927\u7bb1\u5b50)\u3002", + "shop-already-owned": "&c\u9019\u5df2\u7d93\u662f\u500b\u5546\u5e97\u4e86\u3002", + "chest-was-removed": "&c\u7bb1\u5b50\u5df2\u88ab\u79fb\u9664\u3002", + "price-too-cheap": "&c\u50f9\u683c\u5fc5\u9808\u5927\u65bc &e${0}", + "no-price-change": "&c\u50f9\u683c\u4e26\u6c92\u6709\u8b8a\u66f4!", + "you-cant-afford-a-new-shop": "&c\u9700\u8981\u82b1\u8cbb {0} \u5143\u624d\u80fd\u5275\u5efa\u5546\u5e97!", + "player-bought-from-your-store-tax": "&c{0} \u5f9e\u60a8\u7684\u5546\u5e97\u8cb7\u4e86 {1} \u500b {2}, \u540c\u6642\u60a8\u88ab\u6536\u53d6 {3} \u5143\u7684\u7a05\u91d1\u3002", + "you-cant-afford-to-change-price": "&c\u60a8\u9700\u8981\u82b1\u8cbb {0} \u5143\u4f86\u66f4\u6539\u5546\u54c1\u50f9\u683c\u3002", + "success-created-shop": "&a\u6210\u529f\u5275\u5efa\u5546\u5e97!!!", + "success-removed-shop": "&a\u5df2\u7d93\u79fb\u9664\u5546\u5e97\u3002", + "shops-arent-locked": "&c\u8acb\u6ce8\u610f\uff0c\u5546\u5e97\u4e26\u6c92\u6709\u4fdd\u8b77\u7bb1\u5b50! \u82e5\u60a8\u60f3\u8981\u907f\u514d\u88ab\u5077\uff0c\u8acb\u7528\u9396\u7bb1\u63d2\u4ef6\u5c07\u7bb1\u5b50\u9396\u4e0a!", + "shop-creation-cancelled": "&c\u5df2\u7d93\u53d6\u6d88\u5275\u5efa\u5546\u5e97\u3002", + "shop-purchase-cancelled": "&c\u5df2\u7d93\u53d6\u6d88\u8cfc\u8cb7\u3002", + "shop-stock-too-low": "&c\u9019\u500b\u5546\u5e97\u53ea\u5269 {0} \u500b {1}\u3002", + "you-cant-afford-to-buy": "&c\u5546\u54c1\u50f9\u683c\u662f {0} \u5143, \u4f46\u662f\u60a8\u53ea\u6709 {1} \u5143\u3002", + "negative-amount": "&c\u6211\u7684\u5929\u554a, \u6c92\u60f3\u5230\u5c45\u7136\u6709\u4eba\u60f3\u8981\u4ea4\u6613\u8ca0\u6578\u7684\u6578\u91cf!", + "not-a-number": "&c\u8f38\u5165\u53ea\u80fd\u662f\u6578\u5b57, \u4f46\u60a8\u8f38\u5165\u4e86 {0}\u3002", + "not-a-integer": "&c\u8f38\u5165\u53ea\u80fd\u662f\u6574\u6578, \u4f46\u60a8\u8f38\u5165\u4e86 {0}\u3002", + "player-bought-from-your-store": "&c{0} \u5f9e\u60a8\u7684\u5546\u5e97\u8cb7\u4e86 {1} \u500b {2}\u3002", + "shop-out-of-stock": "&5\u60a8\u5728 {0}, {1}, {2} \u8ca9\u8ce3 {3} \u7684\u5546\u5e97\u5df2\u7d93\u552e\u947f\u4e00\u7a7a!", + "shop-has-no-space": "&c\u9019\u500b\u5546\u5e97\u53ea\u80fd\u518d\u6536\u8cfc {0} \u500b {1} \u800c\u5df2!", + "you-dont-have-that-many-items": "&c\u60a8\u7684\u8eab\u4e0a\u53ea\u6709 {0} \u500b {1}!", + "the-owner-cant-afford-to-buy-from-you": "&c\u9019\u6a23\u7e3d\u5171\u662f {0} \u5143, \u4f46\u662f\u5e97\u4e3b\u53ea\u6709 {1} \u5143\u3002", + "player-sold-to-your-store": "&a{0} \u8ce3\u4e86 {1} \u500b {2} \u7d66\u60a8\u3002", + "shop-out-of-space": "&5\u60a8\u5728 {0}, {1}, {2} \u7684\u5546\u5e97\u73fe\u5728\u5df2\u7d93\u6eff\u4e86!", + "fee-charged-for-price-change": "&a\u60a8\u4ed8\u4e86 &c{0}&a \u5143\u4ee5\u66f4\u6539\u5546\u5e97\u50f9\u683c\u3002", + "price-is-now": "&a\u73fe\u5728\u60a8\u5546\u5e97\u7684\u5b9a\u50f9\u662f &e{0} \u5143\u3002", + "thats-not-a-number": "&c\u7121\u6548\u7684\u6578\u5b57", + "no-price-given": "&c\u8acb\u63d0\u4f9b\u4e00\u500b\u6709\u6548\u7684\u50f9\u683c!", + "average-price-nearby": "&a\u9644\u8fd1\u5546\u5e97\u7684\u5e73\u5747\u50f9\u683c\u70ba: &e{0} \u5143\u3002", + "shop-has-changed": "&c\u60a8\u5617\u8a66\u4ea4\u6613\u7684\u5546\u5e97\u5728\u60a8\u9ede\u64ca\u5f8c\u5df2\u7d93\u6709\u8b8a\u52d5!", + "shop-not-exist": "&c\u6c92\u6709\u627e\u5230\u5546\u5e97\u3002", + "nearby-shop-this-way": "&a\u9019\u500b\u5546\u5e97\u96e2\u60a8\u6709 {0} \u683c\u7684\u8ddd\u96e2\u3002", + "no-nearby-shop": "&c\u9644\u8fd1\u6c92\u6709\u4efb\u4f55 {0} \u7684\u5546\u5e97\u3002", + "buying-more-than-selling": "&c\u63d0\u9192: \u60a8\u7684\u6536\u8cfc\u50f9\u683c\u6bd4\u8ca9\u8ce3\u50f9\u683c\u9ad8!", + "not-enough-space": "&c\u60a8\u53ea\u5269\u4e0b {0} \u683c\u7a7a\u9593\u53ef\u4ee5\u88dd\u6771\u897f!", + "refill-success": "&a\u88dc\u8ca8\u6210\u529f!", + "empty-success": "&a\u6e05\u7a7a\u5546\u54c1\u6210\u529f!", + "admin-shop": "\u7ba1\u7406\u54e1\u5546\u5e97", + "unknown-owner": "\u672a\u77e5", + "owner-bypass-check": "&e\u7565\u904e\u4e86\u6240\u6709\u6aa2\u67e5, \u4ea4\u6613\u5df2\u7d93\u6210\u529f! (\u60a8\u662f\u5e97\u4e3b)\u3002", + "reached-maximum-can-create": "&c\u60a8\u5df2\u7d93\u5275\u5efa\u4e86 {0}\/{1} \u500b\u5546\u5e97!", + "restricted-prices": "&c{0} \u5143\u662f\u7121\u6548\u7684\u50f9\u683c: \u6700\u9ad8 {1} \u5143, \u6700\u4f4e {2} \u5143\u3002", + "no-enough-money-to-keep-shops": "&c\u60a8\u7684\u9322\u4e0d\u5920\u7e73\u7a05, \u6240\u4ee5\u60a8\u7684\u6240\u6709\u5546\u5e97\u5df2\u88ab\u522a\u9664...", + "nothing-to-flush": "&a\u6c92\u6709\u95dc\u65bc\u5546\u5e97\u7684\u65b0\u6d88\u606f\u3002", + "break-shop-use-supertool": "&e\u60a8\u53ef\u4ee5\u4f7f\u7528\u8d85\u7d1a\u5de5\u5177\u7834\u58de\u5546\u5e97\u3002", + "failed-to-put-sign": "&c\u60a8\u7684\u5546\u5e97\u5468\u570d\u6c92\u6709\u8db3\u5920\u7684\u7a7a\u9593\u53ef\u4ee5\u653e\u5546\u5e97\u7684\u8cc7\u8a0a\u544a\u793a\u724c\u3002", + "failed-to-paste": "&c\u7121\u6cd5\u5c07\u8cc7\u6599\u4e0a\u50b3\u81f3 Pastebin, \u8acb\u6aa2\u67e5\u60a8\u7684\u7db2\u7d61\u518d\u91cd\u8a66\u3002(\u8a73\u898b\u63a7\u5236\u53f0)", + "warn-to-paste": "&e\u6b63\u5728\u6536\u96c6\u8cc7\u6599\u4e26\u4e0a\u50b3\u5230 Pastebin, \u9019\u53ef\u80fd\u9700\u8981\u4e00\u6bb5\u6642\u9593\u3002&c&l\u8b66\u544a! &c\u8cc7\u6599\u4e0a\u50b3\u5f8c\u5c07\u4fdd\u7559\u4e00\u9031\uff0c\u53ef\u80fd\u6703\u5305\u542b\u60a8\u7684\u4f3a\u670d\u5668\u8a2d\u5b9a\u8207\u5176\u4ed6\u654f\u611f\u8cc7\u8a0a\uff0c\u8acb\u78ba\u8a8d\u60a8\u53ea\u5c07\u9023\u7d50\u50b3\u7d66\u60a8&l\u4fe1\u4efb\u7684\u5de5\u4f5c\u4eba\u54e1\u6216\u662f\u958b\u767c\u4eba\u54e1\u3002", + "price-too-high": "&c\u5546\u5e97\u50f9\u683c\u6709\u9ede\u592a\u9ad8\u4e86! \u8acb\u8a2d\u5b9a\u5728 {0} \u4ee5\u5167\u3002", + "you-cant-create-shop-in-there": "&c\u60a8\u6c92\u6709\u5728\u9019\u500b\u5730\u65b9\u5275\u5efa\u5546\u5e97\u7684\u6b0a\u9650\u3002", + "unknown-player": "&c\u73a9\u5bb6\u4e0d\u5b58\u5728, \u8acb\u6aa2\u67e5\u60a8\u8f38\u5165\u7684\u73a9\u5bb6\u540d\u7a31!", + "shop-staff-cleared": "&c\u5df2\u7d93\u5c07\u6240\u6709\u5e97\u54e1\u5f9e\u60a8\u7684\u5546\u5e97\u79fb\u9664!", + "shop-staff-added": "&a\u6210\u529f\u65b0\u589e {0} \u70ba\u60a8\u7684\u5e97\u54e1!", + "shop-staff-deleted": "&a\u5df2\u7d93\u5f9e\u5e97\u54e1\u4e2d\u79fb\u9664 {0}\u3002", + "no-permission-build": "&c\u60a8\u7121\u6cd5\u5728\u9019\u908a\u5275\u5efa\u5546\u5e97\u3002", + "success-change-owner-to-server": "&a\u6210\u529f\u5c07\u5546\u5e97\u64c1\u6709\u8005\u8f49\u4ea4\u7d66\u4f3a\u670d\u5668!", + "flush-finished": "&a\u5df2\u7d93\u6210\u529f\u66f4\u65b0\u8a0a\u606f\u3002", + "purchase-failed": "&c\u4ea4\u6613\u5931\u6557: \u767c\u751f\u932f\u8aa4, \u8acb\u806f\u7e6b\u7ba1\u7406\u54e1\u3002", + "no-pending-action": "&c\u60a8\u6c92\u6709\u5f85\u8655\u7406\u7684\u64cd\u4f5c", + "permission-denied-3rd-party": "&c\u5b58\u53d6\u88ab\u62d2: \u7b2c\u4e09\u65b9\u63d2\u4ef6 [{0}]\u3002", + "menu": { + "successful-purchase": "&a\u6210\u529f\u8cfc\u8cb7: ", + "successfully-sold": "&a\u6210\u529f\u8ce3\u51fa: ", + "item-name-and-price": "&a\u5171 &e{2} &a\u5143\u7684 &e{0} &a\u500b &e{1}", + "sell-tax": "&a\u60a8\u4ed8\u4e86 &e{0} &a\u5143\u7684\u7a05\u3002", + "sell-tax-self": "&a\u8ce3\u7d66\u81ea\u5df1\u7684\u5546\u5e97\u4e0d\u9700\u8981\u7e73\u7a05\u3002", + "enchants": "&5\u9644\u9b54", + "stored-enchants": "&5\u5df2\u7d93\u6709\u7684\u9644\u9b54", + "shop-information": "&a\u5546\u5e97\u8cc7\u8a0a: ", + "owner": "&a\u5546\u5e97\u4e3b\u4eba: {0}", + "item": "&a\u5546\u54c1: &e{0}", + "preview": "&b[\u9810\u89bd\u5546\u54c1]", + "space": "&a\u7a7a\u9593: &e{0}", + "stock": "&a\u5eab\u5b58: &e{0}", + "price-per": "&a\u50f9\u683c: &e\u4e00\u500b {0} {1} \u5143", + "total-value-of-chest": "&a\u7bb1\u5b50\u4e2d\u7269\u54c1\u7e3d\u50f9: &e{0} \u5143", + "damage-percent-remaining": "&a\u8010\u4e45\u5ea6: &e\u5269\u9918 {0}%", + "this-shop-is-buying": "&a\u6b64\u5546\u5e97\u662f &d\u6536\u8cfc\u7269\u54c1&a \u7684\u5546\u5e97\u3002", + "this-shop-is-selling": "&a\u6b64\u5546\u5e97\u662f &b\u8ce3\u51fa\u7269\u54c1&a \u7684\u5546\u5e97\u3002", + "effects": "&a\u85e5\u6c34\u6548\u679c: &e{0}", + "commands": { + "preview": "\/qs silentpreview {0} {1} {2} {3}" + } + }, + "bypassing-lock": "&c\u6253\u958b\u4e86\u4e00\u500b\u4e0a\u9396\u7684\u5546\u5e97!", + "that-is-locked": "&c\u6b64\u5546\u5e97\u5df2\u7d93\u4e0a\u9396!", + "how-many-buy": "&a\u5728\u804a\u5929\u5ba4\u4e2d\u8f38\u5165\u60a8\u60f3\u8981 &b\u8cfc\u8cb7 &a\u7684\u6578\u91cf, \u60a8\u53ef\u4ee5\u8cfc\u8cb7 &e{0} &a\u500b\u3002\u8f38\u5165 &ball &a\u8cfc\u8cb7\u5168\u90e8\u3002", + "how-many-sell": "&a\u5728\u804a\u5929\u5ba4\u4e2d\u8f38\u5165\u60a8\u60f3\u8981 &d\u51fa\u552e &a\u7684\u6578\u91cf, \u60a8\u6709 &e{0} &a\u500b\u53ef\u4ee5\u51fa\u552e\u3002\u8f38\u5165 &ball &a\u8ce3\u51fa\u5168\u90e8\u3002", + "not-allowed-to-create": "&c\u60a8\u7121\u6cd5\u5728\u6b64\u5275\u5efa\u5546\u5e97\u3002", + "blacklisted-item": "&c\u9019\u4ef6\u7269\u54c1\u5df2\u88ab\u4f3a\u670d\u5668\u7981\u6b62\u8ca9\u552e!", + "how-much-to-trade-for": "&a\u8acb\u5728\u804a\u5929\u5ba4\u4e2d\u8f38\u5165\u6bcf\u500b &e{0} &a\u7684\u5b9a\u50f9:", + "command": { + "toggle-unlimited": { + "unlimited": "&a\u9019\u500b\u5546\u5e97\u73fe\u5728\u5df2\u7d93\u6c92\u6709\u6578\u91cf\u9650\u5236\u3002", + "limited": "&a\u9019\u500b\u5546\u5e97\u73fe\u5728\u5df2\u7d93\u6062\u5fa9\u6578\u91cf\u9650\u5236\u3002" + }, + "no-owner-given": "&c\u5546\u5e97\u6c92\u6709\u6307\u5b9a\u64c1\u6709\u8005, \u4f7f\u7528 &a\/qs setowner <\u73a9\u5bb6\u540d\u7a31> &c\u4f86\u8a2d\u5b9a\u3002", + "new-owner": "&a\u65b0\u5546\u5e97\u4e3b\u4eba: &e{0}", + "now-buying": "&a\u5546\u5e97\u73fe\u5728 &d\u6536\u8cfc &e{0}", + "now-selling": "&a\u5546\u5e97\u73fe\u5728 &b\u8ca9\u8ce3 &e{0}", + "cleaning": "&a\u6b63\u5728\u6e05\u9664\u5df2\u7d93\u88ab\u6383\u8cfc\u4e00\u7a7a ( \u5eab\u5b58\u70ba 0 ) \u7684\u5546\u5e97...", + "reloading": "&a\u91cd\u65b0\u8f09\u5165\u4e2d...", + "cleaned": "&a\u5df2\u7d93\u79fb\u9664 &e{0} &a\u500b\u5546\u5e97", + "no-type-given": "&c\u7528\u6cd5: \/qs find <\u7269\u54c1>", + "no-amount-given": "&c\u6c92\u6709\u63d0\u4f9b\u6578\u91cf, \u8acb\u4f7f\u7528: &a\/qs refill <\u6578\u91cf>", + "now-debuging": "&a\u6210\u529f\u5207\u63db\u5230\u958b\u767c (\u9664\u932f) \u6a21\u5f0f, \u91cd\u65b0\u8f09\u5165 QuickShop \u4e2d...", + "now-nolonger-debuging": "&a\u6210\u529f\u5207\u63db\u5230\u7522\u54c1 (\u975e\u9664\u932f) \u6a21\u5f0f\uff0c\u91cd\u65b0\u8f09\u5165 QuickShop \u4e2d...", + "wrong-args": "&c\u53c3\u6578\u932f\u8aa4, \u4f7f\u7528 \/qs help \u67e5\u770b\u6307\u4ee4\u5217\u8868", + "description": { + "title": "&aQuickShop \u6307\u4ee4\u5217\u8868", + "unlimited": "&e\u8b93\u5546\u5e97\u6c92\u6709\u6536\u552e\u6578\u91cf\u4e0a\u9650", + "setowner": "&e\u6539\u8b8a\u5e97\u4e3b", + "owner": "&e\u6539\u8b8a\u5e97\u4e3b", + "buy": "&e\u5c07\u5546\u5e97\u66f4\u6539\u70ba &d\u6536\u8cfc&e \u6a21\u5f0f", + "sell": "&e\u5c07\u5546\u5e97\u66f4\u6539\u70ba &b\u8ca9\u8ce3&e \u6a21\u5f0f", + "price": "&e\u66f4\u6539\u60a8\u5546\u5e97\u7684\u8cb7\u8ce3\u50f9\u683c", + "clean": "&e\u522a\u9664\u6240\u6709 (\u5df2\u8f09\u5165) \u6c92\u6709\u5546\u54c1\u7684\u5546\u5e97", + "find": "&e\u627e\u5230\u8ddd\u96e2\u60a8\u6700\u8fd1\u7684\u8cb7\u8ce3\u7279\u5b9a\u5546\u54c1\u7684\u5546\u5e97", + "reload": "&e\u91cd\u65b0\u8f09\u5165 QuickShop \u7684 config.yml \u6587\u4ef6", + "refill": "&e\u5c07\u4e00\u5b9a\u6578\u91cf\u7684\u5546\u54c1\u52a0\u5230\u5546\u5e97", + "empty": "&e\u5f9e\u5546\u5e97\u6e05\u7a7a\u6240\u6709\u5546\u54c1", + "debug": "&e\u5207\u63db\u5230\u958b\u767c\u6a21\u5f0f", + "create": "&e\u5728\u76ee\u6a19\u5132\u7269\u7bb1\u5275\u5efa\u4e00\u500b\u65b0\u5546\u5e97", + "fetchmessage": "&e\u7372\u53d6\u672a\u8b80\u53d6\u7684\u5546\u5e97\u8a0a\u606f", + "info": "&e\u986f\u793a QuickShop \u7684\u7d71\u8a08\u8cc7\u6599", + "paste": "&e\u81ea\u52d5\u5c07\u4f3a\u670d\u5668\u8cc7\u6599\u50b3\u9001\u5230 Pastebin \u4e0a", + "staff": "&e\u7ba1\u7406\u60a8\u7684\u5546\u5e97\u5e97\u54e1", + "remove": "&e\u79fb\u9664\u60a8\u6240\u770b\u8457\u7684\u5546\u5e97", + "amount": "&e\u5c07\u60a8\u7684\u52d5\u4f5c\u57f7\u884c\u6307\u5b9a\u7684\u6b21\u6578 (\u9069\u7528\u65bc\u804a\u5929\u63d2\u4ef6\u7684\u554f\u984c)", + "about": "&e\u986f\u793a\u95dc\u65bc QuickShop \u7684\u8a0a\u606f", + "help": "&e\u986f\u793a QuickShop \u7684\u6307\u4ee4", + "supercreate": "&e\u5275\u5efa\u4e00\u500b\u7565\u904e\u6240\u6709\u4fdd\u8b77\u6aa2\u67e5\u7684\u5546\u5e97" + } + }, + "signs": { + "selling": "\u8ca9\u8ce3 {0} \u500b", + "header": "&c{0}", + "buying": "\u6536\u8cfc {0} \u500b", + "item": "{0}", + "price": "\u6bcf\u500b {0}", + "unlimited": "\u7121\u4e0a\u9650" + }, + "controlpanel": { + "setowner": "&a\u5e97\u4e3b: &b{0} &e[&d&l\u8b8a\u66f4&e]", + "infomation": "&a\u5546\u5e97\u63a7\u5236\u9762\u677f:", + "setowner-hover": "&e\u9ede\u64ca\u8b8a\u66f4\u5e97\u4e3b\u3002", + "unlimited": "&a\u7121\u9650\u5236: {0} &e[&d&l\u5207\u63db&e]", + "unlimited-hover": "&e\u9ede\u64ca\u5207\u63db\u5546\u5e97\u8cb7\u8ce3\u7121\u4e0a\u9650\u6a21\u5f0f\u3002", + "mode-selling": "&a\u5546\u5e97\u6a21\u5f0f: &b\u8ca9\u8ce3 &e[&d&l\u5207\u63db&e]", + "mode-selling-hover": "&e\u9ede\u64ca\u5c07\u5546\u5e97\u8b8a\u6210\u6536\u8cfc\u6a21\u5f0f\u3002", + "mode-buying": "&a\u5546\u5e97\u6a21\u5f0f: &b\u6536\u8cfc &e[&d&l\u5207\u63db&e]", + "mode-buying-hover": "&e\u9ede\u64ca\u5c07\u5546\u5e97\u8b8a\u6210\u8ca9\u8ce3\u6a21\u5f0f\u3002", + "price": "&a\u50f9\u9322: &b{0} &e[&d&l\u8a2d\u5b9a&e]", + "price-hover": "&e\u9ede\u64ca\u8b8a\u66f4\u5546\u54c1\u50f9\u9322\u3002", + "refill": "&a\u88dc\u8ca8: \u91cd\u65b0\u586b\u5145\u5546\u54c1 &e[&d&lOK&e]", + "refill-hover": "&e\u9ede\u64ca\u91cd\u65b0\u586b\u5145\u5546\u54c1\u3002", + "empty": "&a\u6e05\u7a7a: \u522a\u9664\u6b64\u5546\u5e97\u5167\u7684\u6240\u6709\u5546\u54c1 &e[&d&lOK&e]", + "empty-hover": "&e\u9ede\u64ca\u6e05\u9664\u5546\u5e97\u5167\u5eab\u5b58\u3002", + "remove": "&c&l[\u522a\u9664\u5546\u5e97]", + "remove-hover": "&e\u9ede\u64ca\u522a\u9664\u5546\u5e97\u3002", + "commands": { + "setowner": "\/qs setowner [\u73a9\u5bb6\u540d\u7a31]", + "unlimited": "\/qs silentunlimited {0} {1} {2} {3}", + "buy": "\/qs silentbuy {0} {1} {2} {3}", + "sell": "\/qs silentsell {0} {1} {2} {3}", + "price": "\/qs price [\u65b0\u50f9\u9322]", + "refill": "\/qs refill [\u6578\u91cf]", + "empty": "\/qs silentempty {0} {1} {2} {3}", + "remove": "\/qs silentremove {0} {1} {2} {3}" + } + }, + "tableformat": { + "full_line": "+---------------------------------------------------+", + "left_half_line": "+--------------------", + "right_half_line": "--------------------+", + "left_begin": "| " + }, + "booleanformat": { + "success": "&a\u2714", + "failed": "&c\u2718" + }, + "tabcomplete": { + "price": "[\u50f9\u9322]", + "range": "[\u7bc4\u570d]", + "amount": "[\u6578\u91cf]" + }, + "updatenotify": { + "buttontitle": "[\u73fe\u5728\u66f4\u65b0]", + "onekeybuttontitle": "[\u4e00\u9375\u66f4\u65b0]", + "list": [ + "\u65b0\u7248\u672c {0} \u5df2\u7d93\u767c\u5e03\u4e86, \u60a8\u9084\u5728\u4f7f\u7528 {1}!", + "\u8e66! \u65b0\u7684\u7248\u672c {0} \u51fa\u4f86\u4e86, \u5feb\u66f4\u65b0!", + "\u9a5a\u559c! \u65b0\u7248\u672c {0} \u51fa\u4f86\u4e86, \u60a8\u7684\u7248\u672c\u662f {1}", + "\u770b\u4f86\u60a8\u9700\u8981\u66f4\u65b0, {0} \u5df2\u7d93\u767c\u5e03\u4e86!", + "\u54ce\u5440! \u65b0\u7248\u672c {0} \u5df2\u7d93\u767c\u5e03\u4e86, \u60a8\u7684\u7248\u672c\u662f {1}!", + "QuickShop \u5df2\u7d93\u66f4\u65b0\u5230 {0} \u4e86, \u60a8\u70ba\u4ec0\u9ebc\u4e0d\u66f4\u65b0\uff1f", + "\u4fee\u5fa9\u4e26\u91cd\u65b0... \u62b1\u6b49 {0} \u5df2\u7d93\u767c\u5e03\u4e86!", + "\u75fe! \u4e0d, \u9019\u4e0d\u662f\u932f\u8aa4, \u53ea\u662f {0} \u7248\u672c\u525b\u767c\u5e03\u4e86!", + "\u6211\u7684\u5929\u554a! {0} \u5df2\u7d93\u51fa\u4f86\u4e86! \u60a8\u600e\u9ebc\u9084\u5728\u4f7f\u7528 {1}\uff1f", + "\u4eca\u65e5\u65b0\u805e: QuickShop \u5df2\u7d93\u91cb\u51fa {0} \u7684\u66f4\u65b0!", + "\u63d2\u4ef6\u5df2\u6b7b, \u60a8\u61c9\u8a72\u8981\u66f4\u65b0\u5230 {0}!", + "Fuze \u6b63\u5728\u549a\u66f4\u65b0 {0}, \u4fdd\u5b58\u66f4\u65b0!", + "\u65b0\u7684\u66f4\u65b0\u6307\u63ee\u5b98 {0} \u525b\u525b\u4e0a\u4efb\u4e86!", + "\u770b\u6211\u7684\u98a8\u683c--- {0} \u7248\u672c\u51fa\u4f86\u4e86, \u60a8\u9084\u5728\u4f7f\u7528 {1} \u7248\u672c", + "\u554a\u554a\u554a! \u662f\u65b0\u7684\u7248\u672c {0}! \u5feb\u66f4\u65b0!", + "\u60a8\u5728\u60f3\u4ec0\u9ebc\uff1f {0} \u5df2\u7d93\u91cb\u51fa\u4e86! \u5feb\u66f4\u65b0!" + ], + "remote-disable-warning": "&c\u9019\u500b\u7248\u672c\u7684 QuickShop \u5df2\u7d93\u88ab\u6a19\u8a18\u70ba\u7981\u7528, \u4ee3\u8868\u9019\u500b\u7248\u672c\u6709\u5341\u5206\u56b4\u91cd\u7684\u554f\u984c\u3002\u5f9e\u6211\u5011\u7684 SpigotMC \u9801\u9762\u7372\u53d6\u66f4\u591a\u8cc7\u8a0a: {0} \u3002\u9019\u5247\u8b66\u544a\u5c07\u6301\u7e8c\u986f\u793a\u5230\u60a8\u4f7f\u7528\u6c92\u6709\u88ab\u7981\u7528\u7684\u7248\u672c\u66ff\u4ee3\u9019\u500b, \u4f46\u4e0d\u5f71\u97ff\u60a8\u7684\u4f3a\u670d\u5668\u904b\u884c\u3002", + "label": { + "unstable": "[\u4e0d\u7a69\u5b9a Unstable]", + "stable": "[\u7a69\u5b9a Stable]", + "lts": "[\u9577\u671f\u652f\u63f4 LTS]", + "qualityverifyed": "[\u54c1\u8cea\u8a8d\u8b49 Quality]", + "github": "[Github]", + "spigotmc": "[SpigotMC]", + "bukkitdev": "[BukkitDev]", + "master": "[Master]" + } + }, + "shop-removed-cause-ongoing-fee": "&c\u7531\u65bc\u60a8\u7684\u9918\u984d\u4e0d\u8db3, \u60a8\u5728 {0} \u7684\u5546\u5e97\u5df2\u7d93\u88ab\u79fb\u9664\u3002", + "digits-reach-the-limit": "&cYou have reach the limit of the digits after the dot in price.", + "complete": "&a\u5b8c\u6210!" +} \ No newline at end of file diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/plugin.yml b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/plugin.yml new file mode 100644 index 0000000..92a9f12 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/plugin.yml @@ -0,0 +1,128 @@ +name: ShopPlugin +main: org.abc.A.QuickShop +version: 114.514 +authors: [minil] + +description: ShopPlugin + +#TIPS: 本题跟原本的插件无关,请不要浪费时间在研究原本的插件上 + +depend: + - LuckPerms + +softdepend: + - Vault + - Reserve + - PlaceholderAPI + - NoCheatPlus + - PermissionEx + - GroupManager + - ClearLag + - Essentials + - CMI + - PlotSquared + - Residence + - Towny + - WorldGuard + - Factions + - ProtocolLib + +api-version: 1.13 + +commands: + qs: + description: QuickShop command + usage: /qs + aliases: [shop,qsshop,qshop,quickshop,chestshop,cshop] + +permissions: + quickshop.create.sell: + description: Allows a player to sell from a shop + default: op + quickshop.create.buy: + description: Allows a player to buy from a shop + default: op + quickshop.create.double: + description: Allows a player to create a double shop + default: op + quickshop.create.changeprice: + description: Allow a player to chyange their shop's price + default: op + quickshop.create.cmd: + description: Allow a player to use /qs create to create a shop + default: op + quickshop.create.admin: + description: Allow a player use /qs supercreate to create a shop bypass all protection checks + default: op + quickshop.use: + description: Allows a player to buy/sell using other players shops + default: true + quickshop.unlimited: + description: Allows a Staff Member to use /qs unlimited and make a shop infinite + default: op + quickshop.bypass.: + description: Allows a player to sell , even if its blacklisted + default: op + quickshop.other.destroy: + description: Allows a Staff Member to destroy other players shops if they are locked in the config + default: op + quickshop.other.open: + description: Allows a Staff Member to open someone elses shop if they are locked in the config + default: op + quickshop.other.price: + description: Allows a Staff Member to change the price of someone elses shop + default: op + quickshop.setowner: + description: Allows a Staff Member to change the owner of any shop + default: op + quickshop.staff: + description: Allow a shop owner to add staff to the shop + default: op + quickshop.find: + description: Allows a player to locate the nearest shop that has a specific item type. Works in a 3 chunk radius. + default: true + quickshop.refill: + description: Allows a Staff Member to refill the shop theyre looking at with the given number of items. + default: op + quickshop.empty: + description: Allows a Staff Member to empty the shop theyre looking at of all items. + default: op + quickshop.debug: + description: Switch to or from developer mode + default: op + quickshop.export: + description: Allows exporting the database to a plain file + default: op + quickshop.alerts: + description: Alert the player when someone tries to cheat with the display item + default: op + quickshop.about: + description: Show QuickShop about message + default: true + quickshop.info: + description: Show QuickShop Statistics. + default: op + quickshop.fetchmessage: + description: Use command /qs fetchmessage to manual fetch shop message from database. Will not effect auto fetch if you have it on... + default: true + quickshop.paste: + description: Command to upload server information to Pastebin. !WARNING, This will upload your data and it may leak your server configuration and other sensitive information. + default: op + quickshop.preview: + description: Permission for preview item to use a GUI + default: true + quickshop.tax: + description: Permission to bypass Tax + default: op + quickshop.cleanghost: + description: Permission to use /qs cleanghost + default: op + quickshop.reset: + description: Permission to use /qs reset + default: op + quickshop.bypasscreatefee: + description: Permission to bypass creation fee + default: op + quickshop.recovery: + description: Permission to use /qs recovery, WARNING DO NOT EXECUTE THIS COMMAND IF YOU DID NOT KNOW WHAT WILL HAPPEND + default: op diff --git a/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/potioni18n.yml b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/potioni18n.yml new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/challenges/reverse/Minecraft.getInstance().Flag1/src/main/resources/potioni18n.yml @@ -0,0 +1 @@ +