From d870885454e40e4fdb2057795c317d4058f1a510 Mon Sep 17 00:00:00 2001 From: Thijs Wiefferink Date: Fri, 21 Mar 2014 18:13:24 +0100 Subject: [PATCH] Version 1.0 --- AreaShop/.gitignore | 2 + AreaShop/.settings/.gitignore | 1 + AreaShop/bin/.gitignore | 1 + AreaShop/config.yml | 64 ++ AreaShop/lang/EN.yml | 116 ++ AreaShop/lang/NL.yml | 116 ++ AreaShop/plugin.yml | 80 ++ .../nl/evolutioncoding/AreaShop/AreaShop.java | 448 ++++++++ .../AreaShop/LanguageManager.java | 179 +++ .../evolutioncoding/AreaShop/RentCheck.java | 21 + .../AreaShop/RightClickListener.java | 89 ++ .../AreaShop/ShopCommands.java | 406 +++++++ .../evolutioncoding/AreaShop/ShopManager.java | 1021 +++++++++++++++++ .../AreaShop/SignBreakListener.java | 162 +++ .../AreaShop/SignChangeListener.java | 235 ++++ 15 files changed, 2941 insertions(+) create mode 100644 AreaShop/.gitignore create mode 100644 AreaShop/.settings/.gitignore create mode 100644 AreaShop/bin/.gitignore create mode 100644 AreaShop/config.yml create mode 100644 AreaShop/lang/EN.yml create mode 100644 AreaShop/lang/NL.yml create mode 100644 AreaShop/plugin.yml create mode 100644 AreaShop/src/nl/evolutioncoding/AreaShop/AreaShop.java create mode 100644 AreaShop/src/nl/evolutioncoding/AreaShop/LanguageManager.java create mode 100644 AreaShop/src/nl/evolutioncoding/AreaShop/RentCheck.java create mode 100644 AreaShop/src/nl/evolutioncoding/AreaShop/RightClickListener.java create mode 100644 AreaShop/src/nl/evolutioncoding/AreaShop/ShopCommands.java create mode 100644 AreaShop/src/nl/evolutioncoding/AreaShop/ShopManager.java create mode 100644 AreaShop/src/nl/evolutioncoding/AreaShop/SignBreakListener.java create mode 100644 AreaShop/src/nl/evolutioncoding/AreaShop/SignChangeListener.java diff --git a/AreaShop/.gitignore b/AreaShop/.gitignore new file mode 100644 index 0000000..239d9b3 --- /dev/null +++ b/AreaShop/.gitignore @@ -0,0 +1,2 @@ +/.project +/.classpath diff --git a/AreaShop/.settings/.gitignore b/AreaShop/.settings/.gitignore new file mode 100644 index 0000000..3b1537c --- /dev/null +++ b/AreaShop/.settings/.gitignore @@ -0,0 +1 @@ +/org.eclipse.jdt.core.prefs diff --git a/AreaShop/bin/.gitignore b/AreaShop/bin/.gitignore new file mode 100644 index 0000000..998e0dd --- /dev/null +++ b/AreaShop/bin/.gitignore @@ -0,0 +1 @@ +/nl diff --git a/AreaShop/config.yml b/AreaShop/config.yml new file mode 100644 index 0000000..2df7791 --- /dev/null +++ b/AreaShop/config.yml @@ -0,0 +1,64 @@ +############################################## +# config.yml of the AreaShop plugin # +# This plugin has been created by NLThijs48 # +# Check the server minecraft.go-craft.com # +# and then the Prison server for a demo # +############################################## + +########## GENERAL ########## +## Chatprefix used for all messages in the chat +chatPrefix: '&2[AreaShop]&r ' +## The character used for the prices of regions, for the euro character use '%euro%' +moneyCharacter: '$' +## Enables / disables debug messages in the console, no need to change +debug: false +## The .yml language file that should be used, provided by this plugin: EN, NL +language: EN +## Maximum total amount of rents and buys together +maximumTotal: 1 + +########## RENTING ########## +## The tag you have to write on the sign for renting a region +rentSign: '[rent]' +## The line that should be placed on the sign when the region is not rented +signRentable: '&2&l[For Rent]' +## The line that should be placed on the sign when the region is rented +signRented: '&4&l[Rented]' +## How much regions a player can rent at the same time, -1 for not limited +maximumRents: 1 +## The percentage of the renting price you get back if you unrent the region (price of time left will be multiplied by this/100) +rentMoneyBack: 100 +## How much seconds between checking if renting has expired (don't put this to low) +checkDelay: 60 +## Flags for the 'For Rent' regions, flags and options to apply when the region is not rented +## All region flags can be used + members, owners, priority and parent. +flagsForRent: + members: -%player% + greeting: '%region% can be rented for %price% per %duration%' +## Flags for the 'Rented' regions, flags and options to apply when the region is rented +## All region flags can be used + members, owners, priority and parent. +flagsRented: + members: +%player% + greeting: '%region% is rented by %player% until %until%' + +########## BUYING ########## +## The tag you have to write on the sign for renting a region +buySign: '[buy]' +## The line that should be placed on the sign when the region is not sold +signBuyable: '&2&l[For Sale]' +## The line that should be placed on the sign when the region is sold +signBuyed: '&4&l[Sold]' +## How much regions a player can buy at the same time, -1 for not limited +maximumBuys: 1 +## The percentage of the buying price you get back if you sell the region +buyMoneyBack: 100 +## Flags for the 'For Sale' regions, flags and options to apply when the region is for sale +## All region flags can be used + members, owners, priority and parent. +flagsForSale: + members: -%player% + greeting: '%region% can be bought for %price%' +## Flags for the 'Sold' regions, flags and options to apply when the region is rented +## All region flags can be used + members, owners, priority and parent. +flagsSold: + members: +%player% + greeting: '%region% is bought by %player%' \ No newline at end of file diff --git a/AreaShop/lang/EN.yml b/AreaShop/lang/EN.yml new file mode 100644 index 0000000..b300727 --- /dev/null +++ b/AreaShop/lang/EN.yml @@ -0,0 +1,116 @@ +################################################### +# English language file for the AreaShop plugin # +################################################### +# Copy this file and change the strings to your # +# favor. Then change the 'language' setting in # +# the config to the filename (excluding .yml) # +################################################### + +########## Command strings +total-maximum: "You can't rent and buy more than %0% region(s) in total" + +cmd-notValid: "That command is not valid, use '/as help' for info" +cmd-onlyByPlayer: "This command can only be run by a player" + +rent-regionNotRentable: "That region is not available for renting" +rent-help: "/as rent " +rent-noPermission: "You don't have permission to rent a region" +rent-maximum: "You can't rent more than %0% region(s)" +rent-payError: "Something went wrong with paying, try again later" +rent-rented: "You rented %0% until %1%" +rent-extended: "You extended your rent of %0% until %1%" +rent-extend: "You can extend your rent by rightclicking the sign again or using /rs rent" +rent-lowMoneyExtend: "You don't have enough money to extend the rent (you have %0% and you need %1%)" +rent-lowMoneyRent: "You don't have enough money to rent this region (you have %0% and you need %1%)" +rent-someoneElse: "Someone else already rented this region" + +buy-help: "/as buy " +buy-noPermission: "You don't have permission to buy a region" +buy-notBuyable: "That region is not available for buying" +buy-maximum: "You can't buy more than %0% region(s)" +buy-payError: "Something went wrong with paying, try again later" +buy-succes: "You succesfully bought %0%" +buy-lowMoney: "You don't have enough money to buy this region (you have %0% and you need %1%)" +buy-yours: "You already own this region" +buy-someoneElse: "Someone else already bought this region" + +unrent-help: "/as unrent " +unrent-noPermission: "You don't have permission to unrent a region" +unrent-noPermissionOther: "You don't have permission to unrent another region" +unrent-notRegistered: "The region can't be unrent because it is not registered for renting" +unrent-notRented: "The region can't be unrent because it is not rented" +unrent-unrented: "Your region has been unrented" +unrent-other: "The region has been unrented for player %0%" +unrent-expired: "Your rent of %0% has expired" + +sell-help: "/as sell " +sell-notRegistered: "The region can't be selled because it is not registered for buying" +sell-notBought: "The region can't be selled because it is not someone's property" +sell-sold: "The region has been sold for player %0%" +sell-soldYours: "Your region has been sold" +sell-noPermission: "You don't have permission to sell a region" +sell-noPermissionOther: "You don't have permission to sell another region" + +rentsigns-updated: "All signs for renting have been updated" +rentsigns-notUpdated: "Not all signs have been updated, maybe reload fixes it" +rentsgins-noPermission: "You don't have permission to update all rentsigns" + +buysigns-updated: "All signs for selling have been updated" +buysigns-notUpdated: "Not all signs have been updated, maybe reload fixes it" +buysigns-noPermission: "You don't have permission to update all buysigns" + +rentregions-updated: "All renting regions have been updated" +rentregions-noPermission: "You don't have permission to update all renting regions" + +buyregions-updated: "All buying regions have been updated" +buyregions-noPermission: "You don't have permission to update all buying regions" + +reload-reloaded: "The config has been reloaded successfully" +reload-noPermission: "You don't have permission to reload the config" + +info-help: "/rs info " +info-all-rents: "Regions registered for renting: %0%" +info-all-noRents: "There are no regions registered for renting" +info-all-buys: "Regions registered for buying: %0%" +info-all-noBuys: "There are no regions registered for buying" +info-rented: "Rented regions: %0%" +info-noRented: "No regions are rented" +info-unrented: "Unrented regions: %0%" +info-noUnrented: "All regions are rented" +info-sold: "Sold regions: %0%" +info-noSold: "No regions are sold" +info-forsale: "Regions for sale: %0%" +info-noForsale: "All regions are sold" +info-playerHelp: "/rs info player " +info-playerRents: "Regions rented by %0%: %1%" +info-playerNoRents: "%0% has not rented a region" +info-playerBuys: "Regions bought by %0%: %1%" +info-playerNoBuys: "%0% has not bought a region" +info-regionHelp: "/rs info region " +info-regionNoRenting: "%0% is not registered for renting" +info-regionRenting: "&6Renting details for %0%" +info-regionRentedBy: "Rented by: %0% until %1%" +info-regionNotRented: "Currently not rented" +info-regionBuying: "&6Buying details for %0%" +info-regionNoBuying: "%0% is not registered for buying" +info-regionNotBought: "Currently not sold" +info-regionBoughtBy: "Bought by: %0%" +info-regionSign: "Sign position: world=%0%, X=%1%, Y=%2%, Z=%3%" +info-regionPriceDuration: "Price: %0% for each %1%" +info-regionPrice: "Price: %0%" + +help-header: "Help page, commands that you can execute" +help-alias: "Command aliases: /areashop, /as" +help-help: "&6/as help &7-&r Shows this help page" +help-info: "&6/as info &7-&r Get info about current regions" +help-rent: "&6/as rent &7-&r Rent a region or extend your current rent" +help-buy: "&6/as buy &7-&r Buy a region" +help-unrent: "&6/as unrent &7-&r Unrent a region" +help-unrentOwn: "&6/as unrent &7-&r Unrent your own region" +help-sell: "&6/as sell &7-&r Sell a region" +help-sellOwn: "&6/as sell &7-&r Sell your own region" +help-updaterentsigns: "&6/as updaterentsigns &7-&r Update all rent signs" +help-updatebuysigns: "&6/as updatebuysigns &7-&r Update all buy signs" +help-updaterentregions: "&6/as updaterentregions &7-&r Update all rent regions" +help-updatebuyregions: "&6/as updatebuyregions &7-&r Update all buy regions" +help-reload: "&6/as reload &7-&r Reload the config and languages" \ No newline at end of file diff --git a/AreaShop/lang/NL.yml b/AreaShop/lang/NL.yml new file mode 100644 index 0000000..43ffc9a --- /dev/null +++ b/AreaShop/lang/NL.yml @@ -0,0 +1,116 @@ +################################################### +# Dutch language file for the AreaShop plugin # +################################################### +# Copy this file and change the strings to your # +# favor. Then change the 'language' setting in # +# the config to the filename (excluding .yml) # +################################################### + +########## Command strings +total-maximum: "Je kunt niet meer dan %0% gebied(en) in totaal huren en kopen" + +cmd-onlyByPlayer: "Dit commando kan alleen door een speler uitgevoert worden" +cmd-notValid: "Dat commando is niet geldig , gebruik '/rs help' voor informatie" + +rent-regionNotRentable: "Dat gebied is niet beschikbaar om te huren" +rent-help: "/as rent " +rent-noPermission: "Je hebt geen toestemming om een gebied te huren" +rent-maximum: "Je kunt niet meer dan %0% gebied(en) huren" +rent-payError: "Er is iets mis gegaan met betalen, probeer het later opnieuw" +rent-rented: "Je hebt %0% tot %1% gehuurd" +rent-extended: "Je hebt je huur van %0% verlengt tot %1%" +rent-extend: "Je kunt je huur verlengen door opnieuw op het bordje te klikken of gebruik te maken van /rs rent" +rent-lowMoneyExtend: "Je hebt niet genoeg geld om de huur te verlengen (je hebt %0% van de %1%)" +rent-lowMoneyRent: "Je hebt niet genoeg geld om het gebied te huren (je hebt %0% van de %1%)" +rent-someoneElse: "Iemand anders heeft dit gebied al gehuurd" + +buy-help: "/as buy " +buy-noPermission: "Je hebt geen toestemming om een gebied te kopen" +buy-notBuyable: "Dat gebied is niet beschikbaar om te kopen" +buy-maximum: "Je kunt niet meer dan %0% gebied(en) kopen" +buy-payError: "Er is iets mis gegaan met betalen, probeer het later opnieuw" +buy-succes: "Je hebt %0% succesvol gekocht" +buy-lowMoney: "Je hebt niet genoeg geld om het gebied te kopen (je hebt %0% van de %1%)" +buy-yours: "Je hebt dit gebied al gekocht" +buy-someoneElse: "Iemand anders heeft dit gebied al gekocht" + +unrent-help: "/as unrent " +unrent-noPermission: "Je hebt geen toestemming om te stoppen met huren" +unrent-noPermissionOther: "Je hebt geen toestemming om iemand anders huur te stoppen" +unrent-notRegistered: "De huur kan niet gestopt worden want het gebied is niet geregistreerd om te huren" +unrent-notRented: "De huur kan niet gestopt worden want het gebied is niet gehuurd" +unrent-unrented: "De huur van je gebied is gestopt" +unrent-other: "De huur voor het gebied is gestopt voor speler %0%" +unrent-expired: "De huur van je gebied %0% is gestopt" + +sell-help: "/as sell " +sell-notRegistered: "Het gebied kan niet verkocht worden want het staat niet geregistreerd om te kopen" +sell-notBought: "Het gebied kan niet verkocht worden want het is niet gekocht" +sell-sold: "Het gebied is verkocht voor speler %0%" +sell-soldYours: "Je gebied is verkocht" +sell-noPermission: "Je hebt geen toestemming om een gebied te verkopen" +sell-noPermissionOther: "Je hebt geen toestemming om een gebied van iemand anders te verkopen" + +rentsigns-updated: "Alle bordjes voor de verhuur zijn geupdate" +rentsigns-notUpdated: "Niet alle bordjes zijn geupdate, een reload zou het op kunnen lossen" +rentsgins-noPermission: "Je hebt geen toestemming om alle verhuur bordjes te updaten" + +buysigns-updated: "All bordjes voor de verkoop zijn geupdate" +buysigns-notUpdated: "Niet alle bordjes zijn geupdate, een reload zou het op kunnen lossen" +buysigns-noPermission: "Je hebt geen toestemming om alle verkoop bordjes te updaten" + +rentregions-updated: "Alle verhuur gebieden zijn geupdate" +rentregions-noPermission: "Je hebt geen toestemming om de verhuur gebieden te updaten" + +buyregions-updated: "Alle verkoop gebieden zijn geupdate" +buyregions-noPermission: "Je hebt geen toestemming om alle verkoop gebieden te updaten" + +reload-reloaded: "De config is succesvol opnieuw ingeladen" +reload-noPermission: "Je hebt geen toestemming om de config opnieuw in te laden" + +info-help: "/as info " +info-all-rents: "Gebieden geregistreerd voor de verhuur: %0%" +info-all-noRents: "Er zijn geen gebieden geregistreerd voor de verhuur" +info-all-buys: "Gebieden geregistreerd voor de verkoop: %0%" +info-all-noBuys: "Er zijn geen gebieden geregistreerd voor de verkoop" +info-rented: "Verhuurde gebieden: %0%" +info-noRented: "Er zijn geen verhuurde gebieden" +info-unrented: "Gebieden te huur: %0%" +info-noUnrented: "Alle gebieden zijn verhuurd" +info-sold: "Verkochte gebieden: %0%" +info-noSold: "Alle gebieden zijn verkocht" +info-forsale: "Gebieden te koop: %0%" +info-noForsale: "Alle gebieden zijn verkocht" +info-playerHelp: "/rs info player " +info-playerRents: "Gebieden gehuurd door %0%: %1%" +info-playerNoRents: "%0% heeft geen gebied gehuurd" +info-playerBuys: "Gebieden gekocht door %0%: %1%" +info-playerNoBuys: "%0% heeft geen gebieden gekocht" +info-regionHelp: "/rs info region " +info-regionNoRenting: "%0% is niet geregistreerd voor verhuur" +info-regionRenting: "&6Huur informatie voor %0%" +info-regionRentedBy: "Gehuurd door: %0% tot %1%" +info-regionNotRented: "Nu niet verhuurd" +info-regionBuying: "&6Verkoop informatie voor %0%" +info-regionNoBuying: "%0% is niet geregistreerd voor verkoop" +info-regionNotBought: "Nu niet verkocht" +info-regionBoughtBy: "Gekocht door: %0%" +info-regionSign: "Plek van het bordje: wereld=%0%, X=%1%, Y=%2%, Z=%3%" +info-regionPriceDuration: "Prijs: %0% voor elke %1%" +info-regionPrice: "Prijs: %0%" + +help-header: "Help pagina, commando's die jij kunt uitvoeren" +help-alias: "Commando aliassen: /areashop, /as" +help-help: "&6/as help &7-&r Laat deze help pagina zien" +help-info: "&6/as info &7-&r Vraag informatie over gebieden op" +help-rent: "&6/as rent &7-&r Huur een gebied of verleng de huur" +help-buy: "&6/as buy &7-&r Koop een gebied" +help-unrent: "&6/as unrent &7-&r Stop de huur van een gebied" +help-unrentOwn: "&6/as unrent &7-&r Stop de huur van een eigen gebied" +help-sell: "&6/as sell &7-&r Verkoop een gebied" +help-sellOwn: "&6/as sell &7-&r Verkoop een eigen gebied" +help-updaterentsigns: "&6/as updaterentsigns &7-&r Update alle huur borden" +help-updatebuysigns: "&6/as updatebuysigns &7-&r Update alle koop borden" +help-updaterentregions: "&6/as updaterentregions &7-&r Update alle huur gebieden" +help-updatebuyregions: "&6/as updatebuyregions &7-&r Update alle koop gebieden" +help-reload: "&6/as reload &7-&r Herlaad de config en de taalbestanden" \ No newline at end of file diff --git a/AreaShop/plugin.yml b/AreaShop/plugin.yml new file mode 100644 index 0000000..b7bb4e6 --- /dev/null +++ b/AreaShop/plugin.yml @@ -0,0 +1,80 @@ +name: AreaShop +main: nl.evolutioncoding.AreaShop.AreaShop +version: 1.0 +depend: [Vault, WorldGuard] +commands: + AreaShop: + description: For all commands use /as help + usage: /AreaShop or /AS + permission: areashop.help + permission-message: You don't have + aliases: [as] +permissions: + areashop.*: + description: Give access to all commands of RegionRent + children: + areashop.help: true + areashop.createrent: true + areashop.createbuy: true + areashop.destroyrent: true + areashop.destroybuy: true + areashop.rent: true + areashop.buy: true + areashop.unrent: true + areashop.info: true + areashop.updaterentsigns: true + areashop.updatebuysigns: true + areashop.updaterentregions: true + areashop.updatebuyregions: true + areashop.reload: true + areashop.help: + description: Allows you to see the help pages + default: true + areashop.rent: + description: Allows you to rent a region + default: true + areashop.buy: + description: Allows you to buy a region + default: true + areashop.unrent: + description: Allows you to unrent a specific region + default: op + areashop.unrentown: + description: Allows you to unrent your own region + default: true + areashop.sell: + description: Allows you to sell a specific region + default: op + areashop.sellown: + description: Allows you to sell your own region + default: true + areashop.createrent: + description: Allows you to set up signs for renting regions + default: op + areashop.createbuy: + description: Allows you to set up signs for buying regions + default: op + areashop.destroyrent: + description: Allows you to break signs used for renting regions + default: op + areashop.destroybuy: + description: Allows you to break signs used for renting regions + default: op + areashop.info: + description: Allows you check the status of regions and players + default: true + areashop.updaterentsigns: + description: Allows you to update all rent signs + default: op + areashop.updatebuysigns: + description: Allows you to update all buy signs + default: op + areashop.updaterentregions: + description: Allows you to update all rent regions + default: op + areashop.updatebuyregions: + description: Allows you to update all buy regions + default: op + areashop.reload: + description: Allows you to reload the config + default: op \ No newline at end of file diff --git a/AreaShop/src/nl/evolutioncoding/AreaShop/AreaShop.java b/AreaShop/src/nl/evolutioncoding/AreaShop/AreaShop.java new file mode 100644 index 0000000..a2cf487 --- /dev/null +++ b/AreaShop/src/nl/evolutioncoding/AreaShop/AreaShop.java @@ -0,0 +1,448 @@ +package nl.evolutioncoding.AreaShop; + +import java.util.ArrayList; +import java.util.logging.Logger; + +import net.milkbowl.vault.economy.Economy; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.Configuration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.java.JavaPlugin; + +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; + +/** + * Main class for the AreaShop plugin + * @author NLThijs48 + */ +public final class AreaShop extends JavaPlugin { + /* General variables */ + private WorldGuardPlugin worldGuard = null; + private Economy economy = null; + private ShopManager shopManager = null; + private LanguageManager languageManager = null; + private boolean configOk = false; + private boolean debug = false; + private String chatprefix = null; + + /* Folder where the language files will be stored */ + public final String languageFolder = "lang"; + + /* Euro tag for in the config */ + public final String currencyEuro = "%euro%"; + + /* Keys for adding things to the hashmap */ + public final String keyWorld = "world"; + public final String keyX = "x"; + public final String keyY = "y"; + public final String keyZ = "z"; + public final String keyDuration = "duration"; + public final String keyPrice = "price"; + public final String keyPlayer = "player"; + public final String keyRentedUntil = "rented"; + public final String keyName = "name"; + + /* Keys for replacing parts of flags */ + public final String tagPlayerName = "%player%"; + public final String tagRegionName = "%region%"; + public final String tagPrice = "%price%"; + public final String tagDuration = "%duration%"; + public final String tagRentedUntil = "%until%"; + + + + /** + * Called on start or reload of the server + */ + public void onEnable(){ + boolean error = false; + + /* Save a copy of the default config.yml if one is not present */ + this.saveDefaultConfig(); + + /* Check the config, loads default if errors */ + configOk = this.checkConfig(); + + /* Check if WorldGuard is present */ + Plugin plugin = getServer().getPluginManager().getPlugin("WorldGuard"); + if (plugin == null || !(plugin instanceof WorldGuardPlugin)) { + this.getLogger().info("Error: WorldGuard plugin is not present or has not loaded correctly"); + error = true; + } else { + worldGuard = (WorldGuardPlugin)plugin; + } + + /* Check if Vault is present */ + RegisteredServiceProvider economyProvider = getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class); + if (economyProvider == null) { + this.getLogger().info("Error: Vault plugin is not present or has not loaded correctly"); + error = true; + } else { + economy = economyProvider.getProvider(); + } + + /* Create a LanguageMananager */ + languageManager = new LanguageManager(this); + + /* Save the chatPrefix */ + chatprefix = this.config().getString("chatPrefix"); + + /* Load all data from files */ + shopManager = new ShopManager(this); + error = error & !shopManager.loadRents(); + shopManager.checkRents(); + error = error & !shopManager.loadBuys(); + + if(error) { + this.getLogger().info("The plugin has not started, fix the errors listed above"); + } else { + /* Register the event listeners */ + this.getServer().getPluginManager().registerEvents(new SignChangeListener(this), this); + this.getServer().getPluginManager().registerEvents(new SignBreakListener(this), this); + this.getServer().getPluginManager().registerEvents(new RightClickListener(this), this); + + /* Start thread for checking renting */ + int checkDelay = Integer.parseInt(this.config().getString("checkDelay"))*20; + new RentCheck(this).runTaskTimer(this, checkDelay, checkDelay); + + /* Bind commands for this plugin */ + getCommand("AreaShop").setExecutor(new ShopCommands(this)); + } + } + + /** + * Called on shutdown or reload of the server + */ + public void onDisable() { + + /* set variables to null to prevent memory leaks */ + worldGuard = null; + economy = null; + shopManager = null; + languageManager = null; + configOk = false; + debug = false; + } + + /** + * Function to get the WorldGuard plugin + * @return WorldGuardPlugin + */ + public WorldGuardPlugin getWorldGuard() { + return worldGuard; + } + + /** + * Function to get the WorldGuard plugin + * @return WorldGuardPlugin + */ + public LanguageManager getLanguageManager() { + return languageManager; + } + + /** + * Function to get the Vault plugin + * @return Economy + */ + public Economy getEconomy() { + return economy; + } + + /** + * Method to get the ShopManager + * @return The shopManager + */ + public ShopManager getShopManager() { + return shopManager; + } + + /** + * Method to send a message to a CommandSender, using chatprefix if it is a player + * @param target The CommandSender you wan't to send the message to (e.g. a player) + * @param key The key to get the translation + * @param params The parameters to inject into the message string + */ + public void message(Object target, String key, Object... params) { + String langString = this.fixColors(languageManager.getLang(key, params)); + if(langString == null) { + this.getLogger().info("Something is wrong with the language file, could not find key: " + key); + } else { + if(target instanceof Player) { + ((Player)target).sendMessage(this.fixColors(chatprefix) + langString); + } else if(target instanceof CommandSender) { + ((CommandSender)target).sendMessage(langString); + } + else if(target instanceof Logger) { + ((Logger)target).info(langString); + } else { + this.getLogger().info("Could not send message, target is wrong: " + langString); + } + } + } + + /** + * Convert color and formatting codes to bukkit values + * @param input Start string with color and formatting codes in it + * @return String with the color and formatting codes in the bukkit format + */ + public String fixColors(String input) { + String result = null; + if(input != null) { + result = input.replaceAll("(&([a-f0-9]))", "\u00A7$2"); + result = result.replaceAll("&k", ChatColor.MAGIC.toString()); + result = result.replaceAll("&l", ChatColor.BOLD.toString()); + result = result.replaceAll("&m", ChatColor.STRIKETHROUGH.toString()); + result = result.replaceAll("&n", ChatColor.UNDERLINE.toString()); + result = result.replaceAll("&o", ChatColor.ITALIC.toString()); + result = result.replaceAll("&r", ChatColor.RESET.toString()); + result = result.replaceAll("€", "\u20AC"); + } + return result; + } + + /** + * Get the currency character, fixes problems with euro character acting weird + * @return Currency character + */ + public String getCurrencyCharacter() { + String result = this.config().getString("moneyCharacter"); + result = result.replace(currencyEuro, "\u20ac"); + return result; + } + + + /** + * Function for quitting the plugin, NOT USED ATM + */ + public void quit() { + this.getLogger().info("Plugin will be stopped"); + Bukkit.getPluginManager().disablePlugin(this); + } + + + /** + * Return the config configured by the user or the default + */ + public Configuration config() { + if(configOk) { + return this.getConfig(); + } else { + return this.getConfig().getDefaults(); + } + } + + /** + * Shows the help page for the player + * @param player The player to show the help to + */ + public void showHelp(CommandSender target) { + /* Set up the list of messages to be sent */ + ArrayList messages = new ArrayList(); + messages.add(this.config().getString("chatPrefix") + languageManager.getLang("help-header")); + messages.add(this.config().getString("chatPrefix") + languageManager.getLang("help-alias")); + if(target.hasPermission("areashop.help")) { + messages.add(languageManager.getLang("help-help")); + } + if(target.hasPermission("areashop.info")) { + messages.add(languageManager.getLang("help-info")); + } + if(target.hasPermission("areashop.rent")) { + messages.add(languageManager.getLang("help-rent")); + } + if(target.hasPermission("areashop.buy")) { + messages.add(languageManager.getLang("help-buy")); + } + if(target.hasPermission("areashop.unrent")) { + messages.add(languageManager.getLang("help-unrent")); + } else if(target.hasPermission("areashop.unrentown")) { + messages.add(languageManager.getLang("help-unrentOwn")); + } + if(target.hasPermission("areashop.sell")) { + messages.add(languageManager.getLang("help-sell")); + } else if(target.hasPermission("areashop.sellown")) { + messages.add(languageManager.getLang("help-sellOwn")); + } + if(target.hasPermission("areashop.updaterentsigns")) { + messages.add(languageManager.getLang("help-updaterentsigns")); + } + if(target.hasPermission("areashop.updatebuysigns")) { + messages.add(languageManager.getLang("help-updatebuysigns")); + } + if(target.hasPermission("areashop.updaterentregions")) { + messages.add(languageManager.getLang("help-updaterentregions")); + } + if(target.hasPermission("areashop.updatebuyregions")) { + messages.add(languageManager.getLang("help-updatebuyregions")); + } + if(target.hasPermission("areashop.reload")) { + messages.add(languageManager.getLang("help-reload")); + } + + /* Send them all */ + for(int i=0; i 14) { + this.getLogger().info("Config-Error: moneyCharacter is longer than 14 characters"); + error++; + } + String maximumTotal = this.getConfig().getString("maximumTotal"); + try { + int maximumTotalInt = Integer.parseInt(maximumTotal); + if(maximumTotalInt < -1) { + this.getLogger().info("Config-Error: maximumTotal must be -1 or higher"); + error++; + } + } catch (NumberFormatException e) { + this.getLogger().info("Config-Error: maximumTotal is not a valid number"); + error++; + } + + /* RENTING */ + String rentSign = this.getConfig().getString("rentSign"); + if (rentSign.length() > 15) { + this.getLogger().info("Config-Error: rentSign is too long, maximum length is 15 characters"); + error++; + } + String signRentable = this.getConfig().getString("signRentable"); + if (signRentable.length() > 15) { + this.getLogger().info("Config-Error: signRentable is too long, maximum length is 15 characters"); + error++; + } + String signRented = this.getConfig().getString("signRented"); + if (signRented.length() > 15) { + this.getLogger().info("Config-Error: signRented is too long, maximum length is 15 characters"); + error++; + } + String maximumRents = this.getConfig().getString("maximumRents"); + try { + int maximumRentsInt = Integer.parseInt(maximumRents); + if(maximumRentsInt < -1) { + this.getLogger().info("Config-Error: maximumRents must be -1 or higher"); + error++; + } + } catch (NumberFormatException e) { + this.getLogger().info("Config-Error: maximumRents is not a valid number"); + error++; + } + String rentMoneyBack = this.getConfig().getString("rentMoneyBack"); + try { + int rentMoneyBackInt = Integer.parseInt(rentMoneyBack); + if(rentMoneyBackInt < 0 || rentMoneyBackInt > 100) { + this.getLogger().info("Config-Error: rentMoneyBack must be between 0 and 100"); + error++; + } + } catch (NumberFormatException e) { + this.getLogger().info("Config-Error: rentMoneyBack is not a valid number"); + error++; + } + String checkDelay = this.getConfig().getString("checkDelay"); + try { + int checkDelayInt = Integer.parseInt(checkDelay); + if(checkDelayInt < 1) { + this.getLogger().info("Config-Error: checkDelay can't be below 1"); + error++; + } + } catch (NumberFormatException e) { + this.getLogger().info("Config-Error: checkDelay is not a valid number"); + error++; + } + + /* BUYING */ + String buySign = this.getConfig().getString("buySign"); + if (buySign.length() > 15) { + this.getLogger().info("Config-Error: buySign is too long, maximum length is 15 characters"); + error++; + } + String signBuyable = this.getConfig().getString("signBuyable"); + if (signBuyable.length() > 15) { + this.getLogger().info("Config-Error: signBuyable is too long, maximum length is 15 characters"); + error++; + } + String signBuyed = this.getConfig().getString("signBuyed"); + if (signBuyed.length() > 15) { + this.getLogger().info("Config-Error: signBuyed is too long, maximum length is 15 characters"); + error++; + } + String maximumBuys = this.getConfig().getString("maximumBuys"); + try { + int maximumBuysInt = Integer.parseInt(maximumBuys); + if(maximumBuysInt < -1) { + this.getLogger().info("Config-Error: maximumBuys must be -1 or higher"); + error++; + } + } catch (NumberFormatException e) { + this.getLogger().info("Config-Error: maximumBuys is not a valid number"); + error++; + } + String buyMoneyBack = this.getConfig().getString("buyMoneyBack"); + try { + int buyMoneyBackInt = Integer.parseInt(buyMoneyBack); + if(buyMoneyBackInt < 0 || buyMoneyBackInt > 100) { + this.getLogger().info("Config-Error: buyMoneyBack must be between 0 and 100"); + error++; + } + } catch (NumberFormatException e) { + this.getLogger().info("Config-Error: buyMoneyBack is not a valid number"); + error++; + } + + /* Load default config if errors have occurred */ + if (error > 0) { + this.getLogger().info("The plugin has " + error + " error(s) in the config, default config will be used"); + } + + /* return true if no errors, false if there are errors */ + return (error == 0); + } + + /** + * Sends an debug message to the console + * @param message The message that should be printed to the console + */ + public void debug(String message) { + if(this.debug) { + this.getLogger().info("Debug: " + message); + } + } + + /** + * Reload the config of the plugin + */ + public void reload() { + this.saveDefaultConfig(); + this.reloadConfig(); + configOk = this.checkConfig(); + chatprefix = this.config().getString("chatPrefix"); + languageManager = new LanguageManager(this); + shopManager.checkRents(); + } + +} + + + + diff --git a/AreaShop/src/nl/evolutioncoding/AreaShop/LanguageManager.java b/AreaShop/src/nl/evolutioncoding/AreaShop/LanguageManager.java new file mode 100644 index 0000000..80efb47 --- /dev/null +++ b/AreaShop/src/nl/evolutioncoding/AreaShop/LanguageManager.java @@ -0,0 +1,179 @@ +package nl.evolutioncoding.AreaShop; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.bukkit.configuration.file.YamlConfiguration; + +public class LanguageManager { + private AreaShop plugin = null; + private String languages[] = {"EN", "NL"}; + private HashMap currentLanguage, defaultLanguage; + + /** + * Constructor + * @param plugin The AreaShop plugin + */ + public LanguageManager(AreaShop plugin) { + this.plugin = plugin; + + /* Save default language files if not present */ + this.saveDefaults(); + + /* Open current language file */ + this.loadLanguage(); + } + + /** + * Saves the default language files if not already present + */ + public void saveDefaults() { + /* Create the language folder if it not exists */ + File langFolder; + langFolder = new File(plugin.getDataFolder() + File.separator + plugin.languageFolder); + if(!langFolder.exists()) { + langFolder.mkdirs(); + } + + /* Create the language files, overwrites if a file already exists */ + /* Overriding is necessary because otherwise with an update the new lang */ + /* files would not be used, when translating your own use another */ + /* file name as the default */ + File langFile; + for(int i=0; i map; + Set set; + YamlConfiguration ymlFile; + + /* Save the current language file to the HashMap */ + currentLanguage = new HashMap(); + File file = new File(plugin.getDataFolder() + File.separator + plugin.languageFolder + File.separator + plugin.config().getString("language") + ".yml"); + ymlFile = YamlConfiguration.loadConfiguration(file); + map = ymlFile.getValues(true); + set = map.keySet(); + try { + for(String key : set) { + currentLanguage.put(key, (String)map.get(key)); + } + } catch(ClassCastException e) {} + + /* Save the default strings to the HashMap */ + defaultLanguage = new HashMap(); + InputStream defConfigStream = plugin.getResource(plugin.languageFolder + "/" + plugin.config().getString("language") + ".yml"); + if (defConfigStream == null) { + defConfigStream = plugin.getResource(plugin.languageFolder + "/" + languages[0]+ ".yml"); + } + ymlFile = YamlConfiguration.loadConfiguration(defConfigStream); + map = ymlFile.getValues(true); + set = map.keySet(); + try { + for(String key : set) { + defaultLanguage.put(key, (String)map.get(key)); + } + } catch(ClassCastException e) {} + } + + /** + * Function to get the string in the language that has been set + * @param key Key to the language string + * @param params The replacements for the %1% tags + * @return String The language string specified with the key + */ + public String getLang(String key, Object... params) { + String result = null; + + /* Get the language string */ + if(currentLanguage.containsKey(key)) { + result = currentLanguage.get(key); + } else { + result = defaultLanguage.get(key); + } + + if(result == null) { + plugin.getLogger().info("Wrong key for getting translation: " + key); + } else { + /* Replace all tags, e.g. %1% */ + for (int i=0; i rent = plugin.getShopManager().getRent(regionName); + HashMap buy = plugin.getShopManager().getBuy(regionName); + + if(rent != null && block.getWorld().getName().equals(rent.get(plugin.keyWorld)) + && rent.get(plugin.keyX).equals(String.valueOf(block.getX())) + && rent.get(plugin.keyY).equals(String.valueOf(block.getY())) + && rent.get(plugin.keyZ).equals(String.valueOf(block.getZ())) ) { + + plugin.getShopManager().rent(event.getPlayer(), regionName); + /* Cancel placing a block */ + event.setCancelled(true); + + } else if(buy != null && block.getWorld().getName().equals(buy.get(plugin.keyWorld)) + && buy.get(plugin.keyX).equals(String.valueOf(block.getX())) + && buy.get(plugin.keyY).equals(String.valueOf(block.getY())) + && buy.get(plugin.keyZ).equals(String.valueOf(block.getZ())) ) { + + plugin.getShopManager().buy(event.getPlayer(), regionName); + /* Cancel placing a block */ + event.setCancelled(true); + + } + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AreaShop/src/nl/evolutioncoding/AreaShop/ShopCommands.java b/AreaShop/src/nl/evolutioncoding/AreaShop/ShopCommands.java new file mode 100644 index 0000000..3cd842c --- /dev/null +++ b/AreaShop/src/nl/evolutioncoding/AreaShop/ShopCommands.java @@ -0,0 +1,406 @@ +package nl.evolutioncoding.AreaShop; + +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.Iterator; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class ShopCommands implements CommandExecutor { + AreaShop plugin; + + /** + * Constructor + * @param plugin The AreaShop plugin + */ + public ShopCommands(AreaShop plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) { + if(command.getName().equalsIgnoreCase("AreaShop")) { + ShopManager shopManager = plugin.getShopManager(); + + /* Commands with 1 argument or more */ + if(args.length > 0 && args[0] != null) { + /* Help command */ + if(args[0].equalsIgnoreCase("help")) { + plugin.showHelp(sender); + } + + /* Renting command */ + else if(args[0].equalsIgnoreCase("rent")) { + if (!(sender instanceof Player)) { + plugin.message(sender, "onlyByPlayer"); + return true; + } + Player player = (Player)sender; + if(args.length > 1 && args[1] != null) { + shopManager.rent(player, args[1]); + } else { + plugin.message(sender, "rent-help"); + } + } + + /* Buying command */ + else if(args[0].equalsIgnoreCase("buy")) { + if (!(sender instanceof Player)) { + plugin.message(sender, "onlyByPlayer"); + return true; + } + Player player = (Player)sender; + if(args.length > 1 && args[1] != null) { + shopManager.buy(player, args[1]); + } else { + plugin.message(player, "buy-help"); + } + } + + /* Info command */ + else if(args[0].equalsIgnoreCase("info")) { + if(args.length > 1 && args[1] != null) { + if(args[1].equalsIgnoreCase("all")) { + String message = ""; + /* Message for rents */ + Iterator it = shopManager.getRents().keySet().iterator(); + if(it.hasNext()) { + message = shopManager.getRent(it.next()).get(plugin.keyName); + while(it.hasNext()) { + message += ", " + shopManager.getRent(it.next()).get(plugin.keyName); + } + } + if(message.equals("")) { + plugin.message(sender, "info-all-noRents"); + } else { + plugin.message(sender, "info-all-rents", message); + } + + /* Message for buys */ + it = shopManager.getBuys().keySet().iterator(); + if(it.hasNext()) { + message = shopManager.getBuy(it.next()).get(plugin.keyName); + while(it.hasNext()) { + message += ", " + shopManager.getBuy(it.next()).get(plugin.keyName); + } + } + if(message.equals("")) { + plugin.message(sender, "info-all-noBuys"); + } else { + plugin.message(sender, "info-all-buys", message); + } + } + else if(args[1].equalsIgnoreCase("rented")) { + String message = ""; + Iterator it = shopManager.getRents().keySet().iterator(); + boolean first = true; + while(it.hasNext()) { + String next = shopManager.getRent(it.next()).get(plugin.keyName); + if(shopManager.getRent(next).get(plugin.keyPlayer) != null) { + if(!first) { + message += ", " + next; + } else { + first = false; + message = next; + } + } + } + if(message.equals("")) { + plugin.message(sender, "info-noRented"); + } else { + plugin.message(sender, "info-rented", message); + } + } else if(args[1].equalsIgnoreCase("forrent")) { + String message = ""; + Iterator it = shopManager.getRents().keySet().iterator(); + boolean first = true; + while(it.hasNext()) { + String next = shopManager.getRent(it.next()).get(plugin.keyName); + if(shopManager.getRent(next).get(plugin.keyPlayer) == null) { + if(!first) { + message += ", " + next; + } else { + first = false; + message = next; + } + } + } + if(message.equals("")) { + plugin.message(sender, "info-noUnrented"); + } else { + plugin.message(sender, "info-unrented", message); + } + } else if(args[1].equalsIgnoreCase("sold")) { + String message = ""; + Iterator it = shopManager.getBuys().keySet().iterator(); + boolean first = true; + while(it.hasNext()) { + String next = shopManager.getBuy(it.next()).get(plugin.keyName); + if(shopManager.getBuy(next).get(plugin.keyPlayer) != null) { + if(!first) { + message += ", "; + } else { + first = false; + } + message += next; + } + } + if(message.equals("")) { + plugin.message(sender, "info-noSold"); + } else { + plugin.message(sender, "info-sold", message); + } + } else if(args[1].equalsIgnoreCase("forsale")) { + String message = ""; + Iterator it = shopManager.getBuys().keySet().iterator(); + boolean first = true; + while(it.hasNext()) { + String next = shopManager.getBuy(it.next()).get(plugin.keyName); + if(shopManager.getBuy(next).get(plugin.keyPlayer) == null) { + if(!first) { + message += ", " + next; + } else { + first = false; + message = next; + } + } + } + if(message.equals("")) { + plugin.message(sender, "info-noForsale"); + } else { + plugin.message(sender, "info-forsale", message); + } + } else if(args[1].equalsIgnoreCase("player")) { + if(args.length > 2 && args[2] != null) { + String message = ""; + Iterator it = shopManager.getRents().keySet().iterator(); + boolean first = true; + while(it.hasNext()) { + String next = shopManager.getRent(it.next()).get(plugin.keyName); + if(shopManager.getRent(next).get(plugin.keyPlayer) != null && shopManager.getRent(next).get(plugin.keyPlayer).equalsIgnoreCase(args[2])) { + if(!first) { + message += ", " + next; + } else { + first = false; + message = next; + } + } + } + if(message.equals("")) { + plugin.message(sender, "info-playerNoRents", args[2]); + } else { + plugin.message(sender, "info-playerRents", args[2], message); + } + + message = ""; + it = shopManager.getBuys().keySet().iterator(); + first = true; + while(it.hasNext()) { + String next = shopManager.getBuy(it.next()).get(plugin.keyName); + if(shopManager.getBuy(next).get(plugin.keyPlayer) != null && shopManager.getBuy(next).get(plugin.keyPlayer).equalsIgnoreCase(args[2])) { + if(!first) { + message += ", "; + } else { + first = false; + } + message += next; + } + } + if(message.equals("")) { + plugin.message(sender, "info-playerNoBuys", args[2]); + } else { + plugin.message(sender, "info-playerBuys", args[2], message); + } + } else { + plugin.message(sender, "info-playerHelp"); + } + } else if(args[1].equalsIgnoreCase("region")) { + if(args.length > 2 && args[2] != null) { + + HashMap rent = shopManager.getRent(args[2]); + HashMap buy = shopManager.getBuy(args[2]); + + if(rent == null) { + plugin.message(sender, "info-regionRenting", args[2]); + plugin.message(sender, "info-regionNoRenting", args[2]); + } else { + plugin.message(sender, "info-regionRenting", rent.get(plugin.keyName)); + plugin.message(sender, "info-regionSign", rent.get(plugin.keyWorld), rent.get(plugin.keyX), rent.get(plugin.keyY), rent.get(plugin.keyZ)); + plugin.message(sender, "info-regionPriceDuration", plugin.getCurrencyCharacter() + rent.get(plugin.keyPrice), rent.get(plugin.keyDuration)); + if(rent.get(plugin.keyPlayer) == null) { + plugin.message(sender, "info-regionNotRented"); + } else { + SimpleDateFormat dateFull = new SimpleDateFormat("dd MMMMMMMMMMMMMMMMM yyyy HH:mm"); + plugin.message(sender, "info-regionRentedBy", rent.get(plugin.keyPlayer), dateFull.format(Long.parseLong(rent.get(plugin.keyRentedUntil)))); + } + } + + if(buy == null) { + plugin.message(sender, "info-regionBuying", args[2]); + plugin.message(sender, "info-regionNoBuying", args[2]); + } else { + plugin.message(sender, "info-regionBuying", buy.get(plugin.keyName)); + plugin.message(sender, "info-regionSign", buy.get(plugin.keyWorld), buy.get(plugin.keyX), buy.get(plugin.keyY), buy.get(plugin.keyZ)); + plugin.message(sender, "info-regionPrice", plugin.getCurrencyCharacter() + buy.get(plugin.keyPrice)); + if(buy.get(plugin.keyPlayer) == null) { + plugin.message(sender, "info-regionNotBought"); + } else { + plugin.message(sender, "info-regionBoughtBy", buy.get(plugin.keyPlayer)); + } + } + } else { + plugin.message(sender, "info-regionHelp"); + } + } else { + plugin.message(sender, "info-help"); + } + } else { + plugin.message(sender, "info-help"); + } + } + + /* Unrenting command */ + else if(args[0].equalsIgnoreCase("unrent")) { + if(args.length > 1 && args[1] != null) { + HashMap rent = shopManager.getRent(args[1]); + if(rent == null) { + plugin.message(sender, "unrent-notRegistered"); + } else { + if(rent.get(plugin.keyPlayer) == null) { + plugin.message(sender, "unrent-notRented"); + } else { + if(sender.hasPermission("areashop.unrent")) { + plugin.message(sender, "unrent-other", rent.get(plugin.keyPlayer)); + shopManager.unRent(args[1]); + } else { + if(sender.hasPermission("areashop.unrentown")) { + if(rent.get(plugin.keyPlayer).equals(sender.getName())) { + plugin.message(sender, "unrent-unrented"); + shopManager.unRent(args[1]); + } else { + plugin.message(sender, "unrent-noPermissionOther"); + } + } else { + plugin.message(sender, "unrent-noPermission"); + } + } + } + } + } else { + plugin.message(sender, "unrent-help"); + } + } + + /* Selling command */ + else if(args[0].equalsIgnoreCase("sell")) { + if(args.length > 1 && args[1] != null) { + HashMap buy = shopManager.getBuy(args[1]); + if(buy == null) { + plugin.message(sender, "sell-notRegistered"); + } else { + if(buy.get(plugin.keyPlayer) == null) { + plugin.message(sender, "sell-notBought"); + } else { + if(sender.hasPermission("areashop.sell")) { + plugin.message(sender, "sell-sold", buy.get(plugin.keyPlayer)); + shopManager.unBuy(args[1]); + } else { + if(sender.hasPermission("areashop.sellown")) { + if(buy.get(plugin.keyPlayer).equals(sender.getName())) { + plugin.message(sender, "sell-soldYours"); + shopManager.unBuy(args[1]); + } else { + plugin.message(sender, "sell-noPermissionOther"); + } + } else { + plugin.message(sender, "sell-noPermission"); + } + } + } + } + } else { + plugin.message(sender, "sell-help"); + } + } + + /* UpdateRentSigns command */ + else if(args[0].equalsIgnoreCase("updaterentsigns")) { + + if(sender.hasPermission("areashop.updaterentsigns")) { + boolean result = plugin.getShopManager().updateRentSigns(); + if(result) { + plugin.message(sender, "rentsigns-updated"); + } else { + plugin.message(sender, "rentsigns-notUpdated"); + } + + } else { + plugin.message(sender, "rentsigns-noPermission"); + } + } + + /* UpdateBuySigns command */ + else if(args[0].equalsIgnoreCase("updatebuysigns")) { + + if(sender.hasPermission("areashop.updatebuysigns")) { + boolean result = plugin.getShopManager().updateBuySigns(); + if(result) { + plugin.message(sender, "buysigns-updated"); + } else { + plugin.message(sender, "buysigns-notUpdated"); + } + } else { + plugin.message(sender, "buysigns-noPermission"); + } + } + + /* updaterentregions command */ + else if(args[0].equalsIgnoreCase("updaterentregions")) { + + if(sender.hasPermission("areashop.updaterentregions")) { + plugin.getShopManager().updateRentRegions(); + plugin.message(sender, "rentregions-updated"); + } else { + plugin.message(sender, "rentregions-noPermission"); + } + } + + /* updatebuyregions command */ + else if(args[0].equalsIgnoreCase("updatebuyregions")) { + + if(sender.hasPermission("areashop.updatebuyregions")) { + plugin.getShopManager().updateBuyRegions(); + plugin.message(sender, "buyregions-updated"); + } else { + plugin.message(sender, "buyregions-noPermission"); + } + } + + /* reload command */ + else if(args[0].equalsIgnoreCase("reload")) { + + if(sender.hasPermission("areashop.reload")) { + plugin.reload(); + plugin.message(sender, "reload-reloaded"); + } else { + plugin.message(sender, "reload-noPermission"); + } + } + + /* Not a valid command */ + else { + plugin.message(sender, "cmd-notValid"); + } + + } else { + plugin.showHelp(sender); + } + return true; + } + return false; + } + +} diff --git a/AreaShop/src/nl/evolutioncoding/AreaShop/ShopManager.java b/AreaShop/src/nl/evolutioncoding/AreaShop/ShopManager.java new file mode 100644 index 0000000..441f9be --- /dev/null +++ b/AreaShop/src/nl/evolutioncoding/AreaShop/ShopManager.java @@ -0,0 +1,1021 @@ +package nl.evolutioncoding.AreaShop; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; + +import net.milkbowl.vault.economy.EconomyResponse; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; + +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.domains.DefaultDomain; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException; +import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException; +import com.sk89q.worldguard.protection.flags.BooleanFlag; +import com.sk89q.worldguard.protection.flags.DefaultFlag; +import com.sk89q.worldguard.protection.flags.DoubleFlag; +import com.sk89q.worldguard.protection.flags.EnumFlag; +import com.sk89q.worldguard.protection.flags.Flag; +import com.sk89q.worldguard.protection.flags.IntegerFlag; +import com.sk89q.worldguard.protection.flags.InvalidFlagFormat; +import com.sk89q.worldguard.protection.flags.SetFlag; +import com.sk89q.worldguard.protection.flags.StateFlag; +import com.sk89q.worldguard.protection.flags.StateFlag.State; +import com.sk89q.worldguard.protection.flags.StringFlag; + +public class ShopManager { + private AreaShop plugin = null; + private ObjectInputStream input = null; + private ObjectOutputStream output = null; + private HashMap> rents = null; + private HashMap> buys = null; + private String rentPath = null; + private String buyPath = null; + + /** + * Constructor, initialize variabeles + * @param plugin + */ + public ShopManager(AreaShop plugin) { + this.plugin = plugin; + rents = new HashMap<>(); + buys = new HashMap<>(); + rentPath = plugin.getDataFolder().getPath() + File.separator + "rents"; + buyPath = plugin.getDataFolder().getPath() + File.separator + "buys"; + + } + + /** + * Add a rent to the list + * @param regionName Name of the region that can be rented + * @param rent Map containing all the info for a rent + */ + public void addRent(String regionName, HashMap rent) { + rents.put(regionName.toLowerCase(), rent); + this.saveRents(); + } + + /** + * Add a buy to the list + * @param regionName Name of the region that can be buyed + * @param buy Map containing all the info for a buy + */ + public void addBuy(String regionName, HashMap buy) { + buys.put(regionName.toLowerCase(), buy); + this.saveBuys(); + } + + /** + * Get a rent from the list + * @param regionName Name of the rent you want to get + * @return The Map with all the values from the rent + */ + public HashMap getRent(String regionName) { + return rents.get(regionName.toLowerCase()); + } + + /** + * Get a buy from the list + * @param regionName Name of the buy you want to get + * @return The Map with all the values from the buy + */ + public HashMap getBuy(String regionName) { + return buys.get(regionName.toLowerCase()); + } + + /** + * Get all rents + * @return The Map with all the values from the rents + */ + public HashMap> getRents() { + return rents; + } + + /** + * Get all buys + * @return The Map with all the values from the buys + */ + public HashMap> getBuys() { + return buys; + } + + /** + * Save all rents to disk + */ + public void saveRents() { + try { + output = new ObjectOutputStream(new FileOutputStream(rentPath)); + output.writeObject(rents); + output.close(); + } catch (IOException e) { + plugin.getLogger().info("File could not be saved: " + rentPath); + } + + } + + /** + * Save all buys to disk + */ + public void saveBuys() { + try { + output = new ObjectOutputStream(new FileOutputStream(buyPath)); + output.writeObject(buys); + output.close(); + } catch (IOException e) { + plugin.getLogger().info("File could not be saved: " + buyPath); + } + + } + + /** + * Unrent a region, reset to unrented + * @param regionName Region that should be unrented + */ + public void unRent(String regionName) { + regionName = regionName.toLowerCase(); + HashMap rent = rents.get(regionName); + + /* Get the time until the region will be rented */ + Long rentedUntil = Long.parseLong(rent.get(plugin.keyRentedUntil)); + Long currentTime = Calendar.getInstance().getTimeInMillis(); + Double timeLeft = (double) ((rentedUntil - currentTime)); + double price = Double.parseDouble(rent.get(plugin.keyPrice)); + double percentage = Integer.parseInt(plugin.config().getString("rentMoneyBack")) / 100; + + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(0); + + String duration = rent.get(plugin.keyDuration); + duration = duration.replace("month", "M"); + duration = duration.replace("months", "M"); + char durationChar = duration.charAt(duration.indexOf(' ')+1); + int durationInt = Integer.parseInt(duration.substring(0, duration.indexOf(' '))); + + if(durationChar == 'm') { + calendar.add(Calendar.MINUTE, durationInt); + } else if(durationChar == 'h') { + calendar.add(Calendar.HOUR, durationInt); + } else if(durationChar == 'd') { + calendar.add(Calendar.DAY_OF_MONTH, durationInt); + } else if(durationChar == 'M') { + calendar.add(Calendar.MONTH, durationInt); + } else if(durationChar == 'y') { + calendar.add(Calendar.YEAR, durationInt); + } + Double timePeriod = (double) (calendar.getTimeInMillis()); + double periods = timeLeft / timePeriod; + double moneyBack = periods * price * percentage; + if(moneyBack > 0) { + /* Give back the money */ + EconomyResponse r = plugin.getEconomy().depositPlayer(rent.get(plugin.keyPlayer), moneyBack); + if(!r.transactionSuccess()) { + plugin.getLogger().info("Something went wrong with paying back money while unrenting"); + } + } + + /* Set the flags and options for the region */ + plugin.getShopManager().setRegionFlags(regionName, plugin.config().getConfigurationSection("flagsForRent"), true); + + /* Debug message */ + plugin.debug(rent.get(plugin.keyPlayer) + " has unrented " + rent.get(plugin.keyName) + ", got " + plugin.getCurrencyCharacter() + moneyBack + " money back"); + + /* Remove the player and renteduntil values */ + rent.remove(plugin.keyPlayer); + rent.remove(plugin.keyRentedUntil); + this.addRent(regionName, rent); + + /* Change the sign to [Rentable] */ + this.updateRentSign(regionName); + + this.saveRents(); + } + + /** + * Sell a buyed region, get part of the money back + * @param regionName + */ + public void unBuy(String regionName) { + regionName = regionName.toLowerCase(); + HashMap buy = buys.get(regionName); + + /* Give part of the buying price back */ + double price = Double.parseDouble(buy.get(plugin.keyPrice)); + double percentage = Integer.parseInt(plugin.config().getString("buyMoneyBack")) / 100; + double moneyBack = price * percentage; + if(moneyBack > 0) { + /* Give back the money */ + EconomyResponse r = plugin.getEconomy().depositPlayer(buy.get(plugin.keyPlayer), moneyBack); + if(!r.transactionSuccess()) { + plugin.getLogger().info("Something went wrong with paying back money while unrenting"); + } + } + + /* Set the flags and options for the region */ + plugin.getShopManager().setRegionFlags(regionName, plugin.config().getConfigurationSection("flagsForSale"), false); + + /* Debug message */ + plugin.debug(buy.get(plugin.keyPlayer) + " has sold " + buy.get(plugin.keyName) + ", got " + plugin.getCurrencyCharacter() + moneyBack + " money back"); + + /* Remove the player and buyeduntil values */ + buy.remove(plugin.keyPlayer); + this.addBuy(regionName, buy); + + /* Change the sign to [Buyable] */ + this.updateBuySign(regionName); + + this.saveBuys(); + } + + /** + * Unrent region that have no time left + */ + public void checkRents() { + /* Check if regions and signs are still present */ + Object[] rentNames = rents.keySet().toArray(); + for(int i=0; i rent = rents.get((String)rentNames[i]); + String rentedUntil = rent.get(plugin.keyRentedUntil); + if(rentedUntil != null) { + Calendar now = Calendar.getInstance(); + Calendar until = Calendar.getInstance(); + until.setTime(new Date(Long.parseLong(rent.get(plugin.keyRentedUntil)))); + if(now.after(until)) { + /* Send message to the player if online */ + Player player = Bukkit.getPlayer(rent.get(plugin.keyPlayer)); + if(player != null) { + plugin.message(player, "unrent-expired", rent.get(plugin.keyName)); + } + this.unRent(rent.get(plugin.keyName)); + } + } + } + } + + /** + * Rent a region + * @param player The player that wants to rent the region + * @param regionName The name of the region you want to rent + * @return true if it succeeded and false if not + */ + public boolean rent(Player player, String regionName) { + regionName = regionName.toLowerCase(); + HashMap rent = plugin.getShopManager().getRent(regionName); + if(rent == null) { + plugin.message(player, "rent-regionNotRentable"); + return false; + } + Block block = Bukkit.getWorld(rent.get(plugin.keyWorld)).getBlockAt(Integer.parseInt(rent.get(plugin.keyX)), Integer.parseInt(rent.get(plugin.keyY)), Integer.parseInt(rent.get(plugin.keyZ))); + + /* Check if the player has permission */ + if(player.hasPermission("areashop.rent")) { + boolean extend = player.getName().equals(rent.get(plugin.keyPlayer)); + /* Check if the region is available for renting */ + if(rent.get(plugin.keyPlayer) == null || extend) { + + if(!extend) { + /* Check if the player can still rent */ + int rentNumber = 0; + Iterator it = rents.keySet().iterator(); + while(it.hasNext()) { + if(player.getName().equals(rents.get(it.next()).get(plugin.keyPlayer))) { + rentNumber++; + } + } + int buyNumber = 0; + it = buys.keySet().iterator(); + while(it.hasNext()) { + if(player.getName().equals(buys.get(it.next()).get(plugin.keyPlayer))) { + buyNumber++; + } + } + int maximumRents = Integer.parseInt(plugin.config().getString("maximumRents")); + if(maximumRents != -1 && rentNumber >= maximumRents) { + plugin.message(player, "rent-maximum", maximumRents); + return false; + } + int maximumTotal = Integer.parseInt(plugin.config().getString("maximumTotal")); + if(maximumTotal != -1 && (rentNumber+buyNumber) >= maximumTotal) { + plugin.message(player, "total-maximum", maximumTotal); + return false; + } + } + + Double price = Double.parseDouble(rent.get(plugin.keyPrice)); + if(plugin.getEconomy().has(player.getName(), block.getWorld().getName(), price)) { + Sign sign = (Sign)block.getState(); + + /* Substract the money from the players balance */ + EconomyResponse r = plugin.getEconomy().withdrawPlayer(player.getName(), price); + if(!r.transactionSuccess()) { + plugin.message(player, "rent-payError"); + return false; + } + + /* Get the time until the region will be rented */ + Calendar calendar = Calendar.getInstance(); + if(extend) { + calendar.setTimeInMillis(Long.parseLong(rent.get(plugin.keyRentedUntil))); + } + + String duration = rent.get(plugin.keyDuration); + duration = duration.replace("month", "M"); + duration = duration.replace("months", "M"); + char durationChar = duration.charAt(duration.indexOf(' ')+1); + int durationInt = Integer.parseInt(duration.substring(0, duration.indexOf(' '))); + if(durationChar == 'm') { + calendar.add(Calendar.MINUTE, durationInt); + } else if(durationChar == 'h') { + calendar.add(Calendar.HOUR, durationInt); + } else if(durationChar == 'd') { + calendar.add(Calendar.DAY_OF_MONTH, durationInt); + } else if(durationChar == 'M') { + calendar.add(Calendar.MONTH, durationInt); + } else if(durationChar == 'y') { + calendar.add(Calendar.YEAR, durationInt); + } + SimpleDateFormat dateFull = new SimpleDateFormat("dd MMMMMMMMMMMMMMMMM yyyy HH:mm"); + + /* Add values to the rent and send it to ShopManager */ + rent.put(plugin.keyRentedUntil, String.valueOf(calendar.getTimeInMillis())); + rent.put(plugin.keyPlayer, player.getName()); + plugin.getShopManager().addRent(sign.getLine(1), rent); + + /* Change the sign */ + this.updateRentSign(regionName); + + /* Set the flags and options for the region */ + plugin.getShopManager().setRegionFlags(regionName, plugin.config().getConfigurationSection("flagsRented"), true); + + /* Send message to the player */ + if(extend) { + plugin.message(player, "rent-extended", sign.getLine(1), dateFull.format(calendar.getTime())); + } else { + plugin.message(player, "rent-rented", sign.getLine(1), dateFull.format(calendar.getTime())); + plugin.message(player, "rent-extend"); + } + plugin.debug(player.getName() + " has rented region " + rent.get(plugin.keyName) + " for " + plugin.getCurrencyCharacter() + price + " until " + dateFull.format(calendar.getTime())); + + this.saveRents(); + return true; + } else { + /* Player has not enough money */ + if(extend) { + plugin.message(player, "rent-lowMoneyExtend", plugin.getCurrencyCharacter() + plugin.getEconomy().getBalance(player.getName(), block.getWorld().getName()), plugin.getCurrencyCharacter() + price); + } else { + plugin.message(player, "rent-lowMoneyRent", plugin.getCurrencyCharacter() + plugin.getEconomy().getBalance(player.getName(), block.getWorld().getName()), plugin.getCurrencyCharacter() + price); + } + } + } else { + plugin.message(player, "rent-someoneElse"); + } + } else { + plugin.message(player, "rent-noPermission"); + } + return false; + } + + + /** + * Buy a region + * @param player The player that wants to buy the region + * @param regionName The name of the region you want to buy + * @return true if it succeeded and false if not + */ + public boolean buy(Player player, String regionName) { + regionName = regionName.toLowerCase(); + HashMap buy = plugin.getShopManager().getBuy(regionName); + if(buy == null) { + plugin.message(player, "rent-notBuyable"); + return true; + } + Block block = Bukkit.getWorld(buy.get(plugin.keyWorld)).getBlockAt(Integer.parseInt(buy.get(plugin.keyX)), Integer.parseInt(buy.get(plugin.keyY)), Integer.parseInt(buy.get(plugin.keyZ))); + + /* Check if the player has permission */ + if(player.hasPermission("areashop.buy")) { + if(buy.get(plugin.keyPlayer) == null) { + + /* Check if the player can still buy */ + int buyNumber = 0; + Iterator it = buys.keySet().iterator(); + while(it.hasNext()) { + if(player.getName().equals(buys.get(it.next()).get(plugin.keyPlayer))) { + buyNumber++; + } + } + int rentNumber = 0; + it = rents.keySet().iterator(); + while(it.hasNext()) { + if(player.getName().equals(rents.get(it.next()).get(plugin.keyPlayer))) { + rentNumber++; + } + } + int maximumBuys = Integer.parseInt(plugin.config().getString("maximumBuys")); + if(maximumBuys != -1 && buyNumber >= maximumBuys) { + plugin.message(player, "buy-maximum", maximumBuys); + return false; + } + int maximumTotal = Integer.parseInt(plugin.config().getString("maximumTotal")); + if(maximumTotal != -1 && (rentNumber+buyNumber) >= maximumTotal) { + plugin.message(player, "total-maximum", maximumTotal); + return false; + } + + /* Check if the player has enough money */ + Double price = Double.parseDouble(buy.get(plugin.keyPrice)); + if(plugin.getEconomy().has(player.getName(), block.getWorld().getName(), price)) { + Sign sign = (Sign)block.getState(); + + /* Substract the money from the players balance */ + EconomyResponse r = plugin.getEconomy().withdrawPlayer(player.getName(), price); + if(!r.transactionSuccess()) { + plugin.message(player, "buy-payError"); + return false; + } + + /* Add values to the buy and send it to ShopManager */ + buy.put(plugin.keyPlayer, player.getName()); + plugin.getShopManager().addBuy(sign.getLine(1), buy); + + /* Change the sign */ + this.updateBuySign(regionName); + + /* Set the flags and options for the region */ + plugin.getShopManager().setRegionFlags(regionName, plugin.config().getConfigurationSection("flagsSold"), false); + + /* Send message to the player */ + plugin.message(player, "buy-succes", sign.getLine(1)); + plugin.debug(player.getName() + " has bought region " + buy.get(plugin.keyName) + " for " + plugin.getCurrencyCharacter() + price); + + this.saveBuys(); + return true; + } else { + /* Player has not enough money */ + plugin.message(player, "buy-lowMoney", plugin.getCurrencyCharacter() + plugin.getEconomy().getBalance(player.getName(), block.getWorld().getName()), plugin.getCurrencyCharacter() + price); + } + } else { + if(player.getName().equals(buy.get(plugin.keyPlayer))) { + plugin.message(player, "buy-yours"); + } else { + plugin.message(player, "buy-someoneElse"); + } + } + } else { + plugin.message(player, "buy-noPermission"); + } + return false; + } + + /** + * Remove a rent from the list + * @param regionName + */ + public boolean removeRent(String regionName) { + regionName = regionName.toLowerCase(); + boolean result = false; + HashMap rent = rents.get(regionName); + if(rent != null) { + if(rent.get(plugin.keyPlayer) != null) { + this.unRent(regionName); + } + /* Delete the sign and the variable */ + Bukkit.getWorld(rent.get(plugin.keyWorld)).getBlockAt(Integer.parseInt(rent.get(plugin.keyX)), Integer.parseInt(rent.get(plugin.keyY)), Integer.parseInt(rent.get(plugin.keyZ))).setType(Material.AIR); + rents.remove(regionName); + this.saveRents(); + result = true; + } + return result; + } + + /** + * Remove a buy from the list + * @param regionName + */ + public boolean removeBuy(String regionName) { + regionName = regionName.toLowerCase(); + boolean result = false; + HashMap buy = buys.get(regionName); + if(buy != null) { + if(buy.get(plugin.keyPlayer) != null) { + this.unBuy(regionName); + } + /* Delete the sign and the variable */ + Bukkit.getWorld(buy.get(plugin.keyWorld)).getBlockAt(Integer.parseInt(buy.get(plugin.keyX)), Integer.parseInt(buy.get(plugin.keyY)), Integer.parseInt(buy.get(plugin.keyZ))).setType(Material.AIR); + buys.remove(regionName); + this.saveBuys(); + result = true; + } + return result; + } + + + /** + * Loads the rents from disk + * @return true if the file is read successfully, else false + */ + @SuppressWarnings("unchecked") + public boolean loadRents() { + boolean error = false; + rents.clear(); + File file = new File(rentPath); + if(file.exists()) { + /* Load all rents from file */ + try { + input = new ObjectInputStream(new FileInputStream(rentPath)); + rents = (HashMap>)input.readObject(); + input.close(); + } catch (IOException | ClassNotFoundException e) { + plugin.getLogger().info("Error: Something went wrong reading file: " + rentPath); + error = true; + } + + if(!error) { + /* Check if regions and signs are still present */ + Object[] rentNames = rents.keySet().toArray(); + for(int i=0; i rent = rents.get(name); + + /* If region is gone delete the rent and the sign */ + if(plugin.getWorldGuard().getRegionManager(Bukkit.getWorld(rent.get(plugin.keyWorld))).getRegion(name) == null) { + this.removeRent(name); + plugin.getLogger().info(name + " does not exist anymore, rent has been deleted"); + } + + /* If the sign is gone remove the rent */ + Block block = Bukkit.getWorld(rent.get(plugin.keyWorld)).getBlockAt(Integer.parseInt(rent.get(plugin.keyX)), Integer.parseInt(rent.get(plugin.keyY)), Integer.parseInt(rent.get(plugin.keyZ))); + boolean remove = true; + if(block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST) { + remove = false; + } + if(remove) { + /* remove the rent */ + if(this.removeRent(name)) { + plugin.getLogger().info("Rent for " + name + " has been deleted, sign is not present"); + } + } + } + + /* Output info to console */ + if(rents.keySet().size() == 1) { + plugin.debug(rents.keySet().size() + " rent loaded"); + } else { + plugin.debug(rents.keySet().size() + " rents loaded"); + } + } + + } else { + this.saveRents(); + plugin.getLogger().info("New file for rents created, should only happen when starting for the first time"); + } + return !error; + } + + /** + * Load the buys file from disk + * @return true if the file is read successfully, else false + */ + @SuppressWarnings("unchecked") + public boolean loadBuys() { + boolean error = false; + buys.clear(); + File file = new File(buyPath); + if(file.exists()) { + /* Load all buys from file */ + try { + input = new ObjectInputStream(new FileInputStream(buyPath)); + buys = (HashMap>)input.readObject(); + input.close(); + } catch (IOException | ClassNotFoundException e) { + plugin.getLogger().info("Error: Something went wrong reading file: " + buyPath); + error = true; + } + + if(!error) { + /* Check if regions and signs are still present */ + Object[] buyNames = buys.keySet().toArray(); + for(int i=0; i buy = buys.get(name); + + /* If region is gone delete the buy and the sign */ + if(plugin.getWorldGuard().getRegionManager(Bukkit.getWorld(buy.get(plugin.keyWorld))).getRegion(name) == null) { + this.removeBuy(name); + plugin.getLogger().info("Region '" + name + "' does not exist anymore, buy has been deleted"); + } + + /* If the sign is gone remove the buy */ + Block block = Bukkit.getWorld(buy.get(plugin.keyWorld)).getBlockAt(Integer.parseInt(buy.get(plugin.keyX)), Integer.parseInt(buy.get(plugin.keyY)), Integer.parseInt(buy.get(plugin.keyZ))); + boolean remove = true; + if(block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST) { + remove = false; + } + if(remove) { + /* remove the buy */ + if(this.removeBuy(name)) { + plugin.getLogger().info("Buy for region '" + name + "' has been deleted, sign is not present"); + } + } + } + + /* Output info to console */ + if(buys.keySet().size() == 1) { + plugin.debug(buys.keySet().size() + " buy loaded"); + } else { + plugin.debug(buys.keySet().size() + " buys loaded"); + } + } + + } else { + this.saveBuys(); + plugin.getLogger().info("New file for buys created, should only happen when starting for the first time"); + } + return !error; + } + + /** + * Update the sign linked to the rent + * @param regionName The region name of wich the sign has to be updated + * @return true if it succeeded, false if not + */ + public boolean updateRentSign(String regionName) { + regionName = regionName.toLowerCase(); + boolean result = false; + HashMap rent = this.getRent(regionName); + if(rent != null) { + /* Get values */ + String world = rent.get(plugin.keyWorld); + String x = rent.get(plugin.keyX); + String y = rent.get(plugin.keyY); + String z = rent.get(plugin.keyZ); + String duration = rent.get(plugin.keyDuration); + String price = rent.get(plugin.keyPrice); + String player = rent.get(plugin.keyPlayer); + String until = rent.get(plugin.keyRentedUntil); + String name = rent.get(plugin.keyName); + Block block = Bukkit.getWorld(world).getBlockAt(Integer.parseInt(x), Integer.parseInt(y), Integer.parseInt(z)); + + if(block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST) { + Sign sign = (Sign)block.getState(); + if(player == null) { + /* Not rented */ + sign.setLine(0, plugin.fixColors(plugin.config().getString("signRentable"))); + sign.setLine(1, name); + sign.setLine(2, duration); + sign.setLine(3, plugin.getCurrencyCharacter() + price); + + } else { + /* Rented */ + SimpleDateFormat date = new SimpleDateFormat("dd-MM HH:mm"); + String dateString = date.format(new Date(Long.parseLong(until))); + + sign.setLine(0, plugin.fixColors(plugin.config().getString("signRented"))); + sign.setLine(1, name); + sign.setLine(2, player); + sign.setLine(3, dateString); + } + sign.update(); + result = true; + } + } + return result; + } + + /** + * Update the sign linked to the buy + * @param regionName The region name of wich the sign has to be updated + * @return true if it succeeded, false if not + */ + public boolean updateBuySign(String regionName) { + regionName = regionName.toLowerCase(); + boolean result = false; + HashMap buy = this.getBuy(regionName); + if(buy != null) { + /* Get values */ + String world = buy.get(plugin.keyWorld); + String x = buy.get(plugin.keyX); + String y = buy.get(plugin.keyY); + String z = buy.get(plugin.keyZ); + String price = buy.get(plugin.keyPrice); + String player = buy.get(plugin.keyPlayer); + String name = buy.get(plugin.keyName); + Block block = Bukkit.getWorld(world).getBlockAt(Integer.parseInt(x), Integer.parseInt(y), Integer.parseInt(z)); + + if(block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST) { + Sign sign = (Sign)block.getState(); + if(player == null) { + /* Not buyed */ + sign.setLine(0, plugin.fixColors(plugin.config().getString("signBuyable"))); + sign.setLine(1, name); + sign.setLine(2, plugin.getCurrencyCharacter() + price); + + } else { + /* Buyed */ + sign.setLine(0, plugin.fixColors(plugin.config().getString("signBuyed"))); + sign.setLine(1, name); + sign.setLine(2, player); + } + sign.update(); + result = true; + } + } + return result; + } + + /** + * Update all rent signs + * @return true if all signs are updated, otherwise false + */ + public boolean updateRentSigns() { + boolean result = true; + + Object[] rentNames = rents.keySet().toArray(); + for(int i=0; i rent = this.getRent(regionName); + if(rent != null) { + if(rent.get(plugin.keyPlayer) == null) { + this.setRegionFlags(regionName, plugin.config().getConfigurationSection("flagsForRent"), true); + } else { + this.setRegionFlags(regionName, plugin.config().getConfigurationSection("flagsRented"), true); + } + } + } + + + /** + * Update all regions registered for renting + */ + public void updateRentRegions() { + Object[] rentNames = rents.keySet().toArray(); + for(int i=0; i buy = this.getBuy(regionName); + if(buy != null) { + if(buy.get(plugin.keyPlayer) == null) { + this.setRegionFlags(regionName, plugin.config().getConfigurationSection("flagsForSale"), false); + } else { + this.setRegionFlags(regionName, plugin.config().getConfigurationSection("flagsSold"), false); + } + } + } + + /** + * Update all regions registered for buying + */ + public void updateBuyRegions() { + Object[] buyNames = buys.keySet().toArray(); + for(int i=0; i flagNames = flags.getKeys(false); + WorldGuardPlugin worldGuard = plugin.getWorldGuard(); + Flag flagType = null; + Object flagValue = null; + + /* Replace tags with values, for example %player% to NLThijs48 */ + HashMap info; + if(isRent) { + info = this.getRent(regionName); + } else { + info = this.getBuy(regionName); + } + + ProtectedRegion region = plugin.getWorldGuard().getRegionManager(Bukkit.getWorld(info.get(plugin.keyWorld))).getRegion(regionName); + + String playerName = info.get(plugin.keyPlayer); + String price = plugin.getCurrencyCharacter() + info.get(plugin.keyPrice); + String duration = info.get(plugin.keyDuration); + String until = null; + if(isRent && playerName != null) { + SimpleDateFormat dateFull = new SimpleDateFormat("dd MMMMMMMMMMMMMMMMM yyyy HH:mm"); + until = dateFull.format(Long.parseLong(info.get(plugin.keyRentedUntil))); + } + + Iterator it = flagNames.iterator(); + while(it.hasNext()) { + String flagName = it.next(); + String value = flags.getString(flagName); + + if(value != null && playerName != null) { + value = value.replace(plugin.tagPlayerName, playerName); + } + if(value != null) { + value = value.replace(plugin.tagRegionName, info.get(plugin.keyName)); + } + if(value != null && price != null) { + value = value.replace(plugin.tagPrice, price); + } + if(value != null && duration != null) { + value = value.replace(plugin.tagDuration, duration); + } + if(value != null && until != null) { + value = value.replace(plugin.tagRentedUntil, until); + } + + /* Check for a couple of options or use as flag */ + if(flagName.equalsIgnoreCase("members")) { + /* Split the string and parse all values */ + String[] names = value.split("\\s*,\\s*"); + DefaultDomain members = region.getMembers(); + for(int i=0; i " + value); + } catch(NumberFormatException e) { + plugin.getLogger().info("The value of flag " + flagName + " is not a number"); + result = false; + } + } else if(flagName.equalsIgnoreCase("parent")) { + ProtectedRegion parentRegion = worldGuard.getRegionManager(Bukkit.getWorld(info.get(plugin.keyWorld))).getRegion(value); + if(parentRegion != null) { + try { + region.setParent(parentRegion); + } catch (CircularInheritanceException e) { + plugin.getLogger().info("The parent set in the config is not correct (circular inheritance)"); + } + } else { + plugin.getLogger().info("The parent set in the config is not correct (region does not exist)"); + } + } else { + flagType = null; + flagValue = null; + + try { + flagType = DefaultFlag.fuzzyMatchFlag(flagName); + if(flagType != null) { + flagValue = flagType.parseInput(worldGuard, null, value); + } + } catch (InvalidFlagFormat e) { + plugin.getLogger().info("The value of flag " + flagName + " is wrong"); + result = false; + } + if(flagValue != null && flagType != null) { + if(flagType instanceof StateFlag) { + if(value.equals("")) { + region.setFlag((StateFlag)flagType, null); + } else { + region.setFlag((StateFlag)flagType, (State)flagValue); + } + } else if(flagType instanceof BooleanFlag) { + if(value.equals("")) { + region.setFlag((BooleanFlag)flagType, null); + } else { + region.setFlag((BooleanFlag)flagType, (Boolean)flagValue); + } + } else if(flagType instanceof IntegerFlag) { + if(value.equals("")) { + region.setFlag((IntegerFlag)flagType, null); + } else { + region.setFlag((IntegerFlag)flagType, (Integer)flagValue); + } + } else if(flagType instanceof DoubleFlag) { + if(value.equals("")) { + region.setFlag((DoubleFlag)flagType, null); + } else { + region.setFlag((DoubleFlag)flagType, (Double)flagValue); + } + } else if(flagType instanceof StringFlag) { + if(value.equals("")) { + region.setFlag((StringFlag)flagType, null); + } else { + region.setFlag((StringFlag)flagType, (String)flagValue); + } + } else if(flagType instanceof SetFlag) { + if(value.equals("")) { + region.setFlag((SetFlag)flagType, null); + } else { + region.setFlag((SetFlag)flagType, (Set)flagValue); + } + } /* else if(flagType instanceof LocationFlag) { + region.setFlag((LocationFlag)flagType, (Location)flagValue); + } */ else if(flagType instanceof EnumFlag) { + if(value.equals("")) { + region.setFlag((EnumFlag)flagType, null); + } else { + region.setFlag((EnumFlag)flagType, (Enum)flagValue); + } + } else { + result = false; + } + plugin.debug("Region " + region.getId() + ", flag " + flagName + " --> " + value); + } else { + result = false; + } + } + } + + try { + worldGuard.getRegionManager(Bukkit.getWorld(info.get(plugin.keyWorld))).save(); + plugin.debug("Regions saved"); + } catch (ProtectionDatabaseException e) { + plugin.getLogger().info("Error: regions could not be saved"); + } + return result; + } +} + + + + + + + + + + + + + + + diff --git a/AreaShop/src/nl/evolutioncoding/AreaShop/SignBreakListener.java b/AreaShop/src/nl/evolutioncoding/AreaShop/SignBreakListener.java new file mode 100644 index 0000000..ca6f2b5 --- /dev/null +++ b/AreaShop/src/nl/evolutioncoding/AreaShop/SignBreakListener.java @@ -0,0 +1,162 @@ +package nl.evolutioncoding.AreaShop; + +import java.util.HashMap; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.event.Listener; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPhysicsEvent; + +/** + * Checks for placement of signs for this plugin + * @author NLThijs48 + */ +public final class SignBreakListener implements Listener { + AreaShop plugin; + + /** + * Constructor + * @param plugin The AreaShop plugin + */ + public SignBreakListener(AreaShop plugin) { + this.plugin = plugin; + } + + + /** + * Called when a block is broken + * @param event The event + */ + @EventHandler(priority = EventPriority.HIGH) + public void onSignBreak(BlockBreakEvent event) { + Block block = event.getBlock(); + /* Check if it is a sign */ + if(block.getType() == Material.WALL_SIGN || block.getType() == Material.SIGN_POST) { + Sign sign = (Sign)(block.getState()); + /* Check if the rent sign is really the same as a saved rent */ + HashMap rent = plugin.getShopManager().getRent(sign.getLine(1)); + HashMap buy = plugin.getShopManager().getBuy(sign.getLine(1)); + if(rent != null && rent.get(plugin.keyWorld).equals(block.getWorld().getName()) + && rent.get(plugin.keyX).equals(String.valueOf(block.getX())) + && rent.get(plugin.keyY).equals(String.valueOf(block.getY())) + && rent.get(plugin.keyZ).equals(String.valueOf(block.getZ())) ) { + /* Remove the rent if the player has permission */ + if(event.getPlayer().hasPermission("areashop.destroyrent")) { + boolean result = plugin.getShopManager().removeRent(sign.getLine(1)); + if(result) { + event.getPlayer().sendMessage(plugin.fixColors(plugin.config().getString("chatPrefix")) + "Renting of the region succesfully removed"); + } + } else { /* Cancel the breaking of the sign */ + event.setCancelled(true); + event.getPlayer().sendMessage(plugin.fixColors(plugin.config().getString("chatPrefix")) + "You don't have permission for destroying a sign for renting a region"); + } + } else if(buy != null && buy.get(plugin.keyWorld).equals(block.getWorld().getName()) + && buy.get(plugin.keyX).equals(String.valueOf(block.getX())) + && buy.get(plugin.keyY).equals(String.valueOf(block.getY())) + && buy.get(plugin.keyZ).equals(String.valueOf(block.getZ())) ) { + /* Remove the buy if the player has permission */ + if(event.getPlayer().hasPermission("areashop.destroybuy")) { + boolean result = plugin.getShopManager().removeBuy(sign.getLine(1)); + if(result) { + event.getPlayer().sendMessage(plugin.fixColors(plugin.config().getString("chatPrefix")) + "Buying of the region succesfully removed"); + } + } else { /* Cancel the breaking of the sign */ + event.setCancelled(true); + event.getPlayer().sendMessage(plugin.fixColors(plugin.config().getString("chatPrefix")) + "You don't have permission for destroying a sign for buying a region"); + } + } + } + } + + /** + * Called when the physics of a block change + * @param event The event + */ + @EventHandler(priority = EventPriority.HIGH) + public void onIndirectSignBreak(BlockPhysicsEvent event){ + Block block = event.getBlock(); + if(block.getType() == Material.SIGN_POST || block.getType() == Material.WALL_SIGN){ + Sign sign = (Sign)block.getState(); + Block attachedTo = block.getRelative(((org.bukkit.material.Sign)sign.getData()).getAttachedFace()); + if(attachedTo.getType() == Material.AIR){ + /* Check if the rent sign is really the same as a saved rent */ + HashMap rent = plugin.getShopManager().getRent(sign.getLine(1)); + HashMap buy = plugin.getShopManager().getBuy(sign.getLine(1)); + if(rent != null && rent.get(plugin.keyWorld).equals(block.getWorld().getName()) + && rent.get(plugin.keyX).equals(String.valueOf(block.getX())) + && rent.get(plugin.keyY).equals(String.valueOf(block.getY())) + && rent.get(plugin.keyZ).equals(String.valueOf(block.getZ())) ) { + /* Remove the rent */ + boolean result = plugin.getShopManager().removeRent(sign.getLine(1)); + if(result) { + plugin.getLogger().info("Renting of region '" + sign.getLine(1) + "' has been removed by indirectly breaking the sign"); + } + } else if(buy != null && buy.get(plugin.keyWorld).equals(block.getWorld().getName()) + && buy.get(plugin.keyX).equals(String.valueOf(block.getX())) + && buy.get(plugin.keyY).equals(String.valueOf(block.getY())) + && buy.get(plugin.keyZ).equals(String.valueOf(block.getZ())) ) { + /* Remove the buy */ + boolean result = plugin.getShopManager().removeBuy(sign.getLine(1)); + if(result) { + plugin.getLogger().info("Buying of region '" + sign.getLine(1) + "' has been removed by indirectly breaking the sign"); + } + } + } + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AreaShop/src/nl/evolutioncoding/AreaShop/SignChangeListener.java b/AreaShop/src/nl/evolutioncoding/AreaShop/SignChangeListener.java new file mode 100644 index 0000000..78a6f1d --- /dev/null +++ b/AreaShop/src/nl/evolutioncoding/AreaShop/SignChangeListener.java @@ -0,0 +1,235 @@ +package nl.evolutioncoding.AreaShop; + +import java.util.HashMap; + +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.SignChangeEvent; + +import com.sk89q.worldguard.protection.managers.RegionManager; + +/** + * Checks for placement of signs for this plugin + * @author NLThijs48 + */ +public final class SignChangeListener implements Listener { + AreaShop plugin; + String chatPrefix; + String rentSign; + String buySign; + String signRentable; + String signBuyable; + + /** + * Constructor + * @param plugin The AreaShop plugin + */ + public SignChangeListener(AreaShop plugin) { + this.plugin = plugin; + chatPrefix = plugin.fixColors(plugin.config().getString("chatPrefix")); + rentSign = plugin.config().getString("rentSign"); + buySign = plugin.config().getString("buySign"); + signRentable = plugin.fixColors(plugin.config().getString("signRentable")); + signBuyable = plugin.fixColors(plugin.config().getString("signBuyable")); + } + + /** + * Called when a sign is changed + * @param event The event + */ + @EventHandler(priority = EventPriority.HIGH) + public void onSignChange(SignChangeEvent event) { + Player player = event.getPlayer(); + + /* Check if the sign is meant for this plugin */ + if(event.getLine(0).contains(rentSign)) { + if(!player.hasPermission("areashop.createrent")) { + player.sendMessage(chatPrefix + "You don't have permission for setting up renting of regions"); + return; + } + + + /* Get the other lines */ + String secondLine = event.getLine(1); + String thirdLine = event.getLine(2); + if(!thirdLine.equals("M")) { + thirdLine = thirdLine.toLowerCase(); + } + String fourthLine = event.getLine(3); + + /* Get the regionManager for accessing regions */ + RegionManager regionManager = plugin.getWorldGuard().getRegionManager(event.getPlayer().getWorld()); + + /* check if all the lines are correct */ + if(secondLine == null || secondLine.length() == 0) { + player.sendMessage(chatPrefix + "You did not specify a region on the second line!"); + return; + } else if(regionManager.getRegion(secondLine) == null) { + player.sendMessage(chatPrefix + "The region you specified does not exist!"); + return; + } else if(plugin.getShopManager().getRent(secondLine) != null) { + player.sendMessage(chatPrefix + "The region you specified already has a sign for renting"); + return; + } else if(thirdLine == null || thirdLine.length() == 0) { + player.sendMessage(chatPrefix + "You did not specify how long the region can be rented, do this on the third line"); + return; + } else if(!this.checkTimeFormat(thirdLine)) { + player.sendMessage(chatPrefix + "The time specified is not in the correct format"); + return; + } else if(fourthLine == null || fourthLine.length() == 0) { + player.sendMessage(chatPrefix + "You did not specify how much the renting costs on the fourth line!"); + return; + } else { + /* Check the fourth line */ + try { + Double.parseDouble(fourthLine); + } catch (NumberFormatException e) { + player.sendMessage(chatPrefix + "You did not specify the renting cost correctly, use a number only"); + return; + } + + /* Set the first line to signRentable */ + event.setLine(0, signRentable); + event.setLine(1, regionManager.getRegion(secondLine).getId()); + event.setLine(3, plugin.getCurrencyCharacter() + fourthLine); + + /* Add rent to the ShopManager */ + HashMap rent = new HashMap(); + rent.put(plugin.keyWorld, event.getBlock().getWorld().getName()); + rent.put(plugin.keyX, String.valueOf(event.getBlock().getX())); + rent.put(plugin.keyY, String.valueOf(event.getBlock().getY())); + rent.put(plugin.keyZ, String.valueOf(event.getBlock().getZ())); + rent.put(plugin.keyDuration, thirdLine); + rent.put(plugin.keyPrice, fourthLine); + rent.put(plugin.keyName, regionManager.getRegion(secondLine).getId()); + plugin.getShopManager().addRent(secondLine, rent); + + /* Set the flags for the region */ + plugin.getShopManager().setRegionFlags(secondLine, plugin.config().getConfigurationSection("flagsForRent"), true); + + player.sendMessage(chatPrefix + "Renting of the region is setup correctly"); + } + } else if (event.getLine(0).contains(buySign)) { + /* Check for permission */ + if(!player.hasPermission("areashop.createbuy")) { + player.sendMessage(chatPrefix + "You don't have permission for setting up buying of regions"); + return; + } + + /* Get the other lines */ + String secondLine = event.getLine(1); + String thirdLine = event.getLine(2); + + /* Get the regionManager for accessing regions */ + RegionManager regionManager = plugin.getWorldGuard().getRegionManager(event.getPlayer().getWorld()); + + /* Check if all the lines are correct */ + if(secondLine == null || secondLine.length() == 0) { + player.sendMessage(chatPrefix + "You did not specify a region on the second line!"); + return; + } else if(regionManager.getRegion(secondLine) == null) { + player.sendMessage(chatPrefix + "The region you specified does not exist!"); + return; + } else if(plugin.getShopManager().getBuy(secondLine) != null) { + player.sendMessage(chatPrefix + "The region you specified already has a sign for buying"); + return; + } else if(thirdLine == null || thirdLine.length() == 0) { + player.sendMessage(chatPrefix + "You did not specify how much the buying costs on the fourth line!"); + return; + } else { + /* Check the fourth line */ + try { + Double.parseDouble(thirdLine); + } catch (NumberFormatException e) { + player.sendMessage(chatPrefix + "You did not specify the buying cost correctly, use a number only"); + return; + } + + /* Set the first line to signbuyable */ + event.setLine(0, signBuyable); + event.setLine(1, regionManager.getRegion(secondLine).getId()); + event.setLine(2, plugin.getCurrencyCharacter() + thirdLine); + + /* Add buy to the ShopManager */ + HashMap buy = new HashMap(); + buy.put(plugin.keyWorld, event.getBlock().getWorld().getName()); + buy.put(plugin.keyX, String.valueOf(event.getBlock().getX())); + buy.put(plugin.keyY, String.valueOf(event.getBlock().getY())); + buy.put(plugin.keyZ, String.valueOf(event.getBlock().getZ())); + buy.put(plugin.keyPrice, thirdLine); + buy.put(plugin.keyName, regionManager.getRegion(secondLine).getId()); + plugin.getShopManager().addBuy(secondLine, buy); + + /* Set the flags for the region */ + plugin.getShopManager().setRegionFlags(secondLine, plugin.config().getConfigurationSection("flagsForSale"), false); + + player.sendMessage(chatPrefix + "Buying of the region is setup correctly"); + } + } + } + + /** + * Checks if the string is a correct time period + * @param time String that has to be checked + * @return true if format is correct, false if not + */ + public boolean checkTimeFormat(String time) { + /* Check if the string is not empty and check the length */ + if(time == null || time.length() <= 1 || time.indexOf(' ') == -1 || time.indexOf(' ') >= (time.length()-1)) { + return false; + } + + /* Check if the suffix is one of these values */ + String[] timeValues = {"m","min","mins","minute","minutes","minuten","minuut", + "h","hour","hours","uur","uren", + "M", "month", "months","maanden","maand", + "d","day","days","dag","dagen", + "y","year","years","jaar","jaren"}; + String suffix = time.substring(time.indexOf(' ')+1, time.length()); + boolean result = false; + for(int i=0; i