diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..a94fa1ff --- /dev/null +++ b/.gitattributes @@ -0,0 +1,14 @@ +# Auto detect text files and perform LF normalization +* text=auto eol=lf +*.java text eol=lf +*.md text eol=lf +*.xml text eol=lf +*.yml text eol=lf +*.ini text=auto +*.csv text=auto +*.txt text=auto +*.bat text eol=crlf +*.cmd text eol=crlf +*.dat binary +*.jar binary +*.class binary diff --git a/.github/workflows/gradleBukkit.yml b/.github/workflows/gradleBukkit.yml new file mode 100644 index 00000000..c728215e --- /dev/null +++ b/.github/workflows/gradleBukkit.yml @@ -0,0 +1,32 @@ +# This workflow will build a Java project with Gradle +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle + +name: Bukkit 1.10.2 + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build with Gradle + run: ./gradlew Bukkit:build + - name: Rename artifacts + run: mv Bukkit/build/libs/MineCity-Bukkit-MC-1.10.2-*.jar Bukkit/build/libs/MineCity-Bukkit-MC-1.10.2.jar + - name: Archive artifacts + uses: actions/upload-artifact@v2 + if: success() + with: + name: MineCityBukkit + path: Bukkit/build/libs/MineCity-Bukkit-MC-1.10.2.jar \ No newline at end of file diff --git a/.github/workflows/gradleForge1.10.2.yml b/.github/workflows/gradleForge1.10.2.yml new file mode 100644 index 00000000..247f479d --- /dev/null +++ b/.github/workflows/gradleForge1.10.2.yml @@ -0,0 +1,36 @@ +# This workflow will build a Java project with Gradle +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle + +name: Forge 1.10.2 + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Setup workspace + run: ./gradlew Forge:1.10.2:setupDecompWorkspace + - name: Setup base workspace + run: ./gradlew Forge:Base:setupDecompWorkspace + - name: Build with Gradle + run: ./gradlew Forge:1.10.2:build + - name: Rename artifacts + run: mv Forge/1.10.2/build/libs/MineCity-Forge-MC1.10.2-*-SNAPSHOT.jar Forge/1.10.2/build/libs/MineCity-Forge-MC-1.10.2.jar + - name: Archive artifacts + uses: actions/upload-artifact@v2 + if: success() + with: + name: MineCityForge1.10.2 + path: Forge/1.10.2/build/libs/MineCity-Forge-MC-1.10.2.jar \ No newline at end of file diff --git a/.github/workflows/gradleForge1.12.2.yml b/.github/workflows/gradleForge1.12.2.yml new file mode 100644 index 00000000..276ac4c5 --- /dev/null +++ b/.github/workflows/gradleForge1.12.2.yml @@ -0,0 +1,34 @@ +# This workflow will build a Java project with Gradle +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle + +name: Forge 1.12.2 + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Setup base workspace + run: ./gradlew Forge:Base:setupDecompWorkspace + - name: Build with Gradle + run: ./gradlew Forge:1.12.2:build + - name: Rename artifacts + run: mv Forge/1.12.2/build/libs/MineCity-Forge-MC1.12.2-*.jar Forge/1.12.2/build/libs/MineCity-Forge-MC-1.12.2.jar + - name: Archive artifacts + uses: actions/upload-artifact@v2 + if: success() + with: + name: MineCityForge1.12.2 + path: Forge/1.12.2/build/libs/MineCity-Forge-MC-1.12.2.jar diff --git a/.github/workflows/gradleForge1.7.10.yml b/.github/workflows/gradleForge1.7.10.yml new file mode 100644 index 00000000..c8ddc810 --- /dev/null +++ b/.github/workflows/gradleForge1.7.10.yml @@ -0,0 +1,38 @@ +# This workflow will build a Java project with Gradle +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle + +name: Forge 1.7.10 + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Setup workspace + run: ./gradlew Forge:1.7.10:setupDecompWorkspace + - name: Setup base workspace + run: ./gradlew Forge:Base:setupDecompWorkspace + - name: Build with Gradle + run: ./gradlew Forge:1.7.10:build + - name: Build with Gradle + run: ./gradlew Forge:1.7.10:build + - name: Rename artifacts + run: mv Forge/1.7.10/build/libs/MineCity-Forge-MC1.7.10-*.jar Forge/1.7.10/build/libs/MineCity-Forge-MC-1.7.10.jar + - name: Archive artifacts + uses: actions/upload-artifact@v2 + if: success() + with: + name: MineCityForge1.7.10 + path: Forge/1.7.10/build/libs/MineCity-Forge-MC-1.7.10.jar \ No newline at end of file diff --git a/Bukkit/src/main/java/br/com/gamemods/minecity/bukkit/MineCityPlugin.java b/Bukkit/src/main/java/br/com/gamemods/minecity/bukkit/MineCityPlugin.java index 9f158430..49888c86 100644 --- a/Bukkit/src/main/java/br/com/gamemods/minecity/bukkit/MineCityPlugin.java +++ b/Bukkit/src/main/java/br/com/gamemods/minecity/bukkit/MineCityPlugin.java @@ -1,412 +1,387 @@ -package br.com.gamemods.minecity.bukkit; - -import br.com.gamemods.minecity.MineCity; -import br.com.gamemods.minecity.MineCityConfig; -import br.com.gamemods.minecity.api.Slow; -import br.com.gamemods.minecity.api.command.Arg; -import br.com.gamemods.minecity.api.command.CommandInfo; -import br.com.gamemods.minecity.api.command.LegacyFormat; -import br.com.gamemods.minecity.api.command.Message; -import br.com.gamemods.minecity.api.permission.PermissionFlag; -import br.com.gamemods.minecity.api.permission.SimpleFlagHolder; -import br.com.gamemods.minecity.api.world.ChunkPos; -import br.com.gamemods.minecity.api.world.WorldDim; -import br.com.gamemods.minecity.bukkit.command.BukkitPermission; -import br.com.gamemods.minecity.bukkit.command.BukkitPlayer; -import br.com.gamemods.minecity.datasource.api.DataSourceException; -import br.com.gamemods.minecity.datasource.api.unchecked.DBConsumer; -import br.com.gamemods.minecity.economy.EconomyLayer; -import br.com.gamemods.minecity.permission.PermissionLayer; -import br.com.gamemods.minecity.sponge.SpongeProviders; -import br.com.gamemods.minecity.vault.VaultProviders; -import net.md_5.bungee.api.ChatColor; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.command.*; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.plugin.PluginManager; -import org.bukkit.plugin.SimplePluginManager; -import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.scheduler.BukkitScheduler; -import org.bukkit.scheduler.BukkitTask; -import org.mcstats.Metrics; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.reflect.Field; -import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; - -@SuppressWarnings("CharsetObjectCanBeUsed") -public class MineCityPlugin extends JavaPlugin -{ - private MineCityBukkit instance; - private BukkitTask reloadTask; - private BukkitTask playerTick; - - private void adjustDefaultFlag(FileConfiguration yaml, String prefix, PermissionFlag flag, boolean def, SimpleFlagHolder holder) - { - boolean allow = yaml.getBoolean(prefix+flag+".allow", def); - String msg = yaml.getString(prefix+flag+".message", ""); - - if(!msg.isEmpty()) - holder.getDefaultMessages().put(flag, Message.string(msg)); - - if(!allow) - holder.deny(flag); - } - - @Slow - @Override - public void onEnable() - { - try - { - Metrics metrics = new Metrics(this); - metrics.start(); - } - catch(Throwable e) - { - getLogger().log(Level.WARNING, "MCStats metrics failed to start", e); - } - - PermissionLayer.register("bukkit", BukkitPermission.PROVIDER); - - if(getServer().getPluginManager().isPluginEnabled("Vault")) - { - getLogger().info("Vault found. Enabling Vault support"); - EconomyLayer.register("vault", VaultProviders.ECONOMY); - PermissionLayer.register("vault", VaultProviders.PERMISSION); - } - - try - { - Class.forName("org.spongepowered.api.Sponge"); - getLogger().info("Sponge API found. Enabling Sponge support"); - EconomyLayer.register("sponge", SpongeProviders.ECONOMY); - PermissionLayer.register("sponge", SpongeProviders.PERMISSION); - } - catch(ClassNotFoundException ignored) - { - getLogger().info("Sponge API not found, disabling Sponge support"); - } - - BukkitTransformer transformer; - try - { - LegacyFormat.BLACK.server = ChatColor.BLACK; - LegacyFormat.DARK_BLUE.server = ChatColor.DARK_BLUE; - LegacyFormat.DARK_GREEN.server = ChatColor.DARK_GREEN; - LegacyFormat.DARK_AQUA.server = ChatColor.DARK_AQUA; - LegacyFormat.DARK_RED.server = ChatColor.DARK_RED; - LegacyFormat.DARK_PURPLE.server = ChatColor.DARK_PURPLE; - LegacyFormat.GOLD.server = ChatColor.GOLD; - LegacyFormat.GRAY.server = ChatColor.GRAY; - LegacyFormat.DARK_GRAY.server = ChatColor.DARK_GRAY; - LegacyFormat.BLUE.server = ChatColor.BLUE; - LegacyFormat.GREEN.server = ChatColor.GREEN; - LegacyFormat.AQUA.server = ChatColor.AQUA; - LegacyFormat.RED.server = ChatColor.RED; - LegacyFormat.LIGHT_PURPLE.server = ChatColor.LIGHT_PURPLE; - LegacyFormat.YELLOW.server = ChatColor.YELLOW; - LegacyFormat.WHITE.server = ChatColor.WHITE; - LegacyFormat.RESET.server = ChatColor.RESET; - LegacyFormat.MAGIC.server = ChatColor.MAGIC; - LegacyFormat.BOLD.server = ChatColor.BOLD; - LegacyFormat.STRIKE.server = ChatColor.STRIKETHROUGH; - LegacyFormat.UNDERLINE.server = ChatColor.UNDERLINE; - LegacyFormat.ITALIC.server = ChatColor.ITALIC; - - transformer = new SpigotTransformer(); - } - catch(NoClassDefFoundError ignored) - { - transformer = new BukkitTransformer(); - } - - try - { - saveDefaultConfig(); - reloadConfig(); - - FileConfiguration yaml = getConfig(); - MineCityConfig config = new MineCityConfig(); - config.dbUrl = yaml.getString("database.url", config.dbUrl); - config.dbUser = Optional.ofNullable(yaml.getString("database.user")).filter(u-> !u.isEmpty()).orElse(null); - config.dbPass = Optional.ofNullable(yaml.getString("database.pass")).filter(p-> !p.isEmpty()).map(String::getBytes).orElse(null); - config.locale = Locale.forLanguageTag(Optional.ofNullable(yaml.getString("language")).filter(l->!l.isEmpty()).orElse("en")); - config.useTitle = yaml.getBoolean("use-titles", true); - config.defaultNatureDisableCities = !yaml.getBoolean("permissions.default.nature.enable-city-creation", true); - config.economy = yaml.getString("economy", "none"); - config.permission = yaml.getString("permission", "bukkit"); - - for(PermissionFlag flag: PermissionFlag.values()) - { - adjustDefaultFlag(yaml, "permissions.default.nature.", flag, flag.defaultNature, config.defaultNatureFlags); - adjustDefaultFlag(yaml, "permissions.default.city.", flag, flag.defaultCity, config.defaultCityFlags); - adjustDefaultFlag(yaml, "permissions.default.plot.", flag, flag.defaultPlot, config.defaultPlotFlags); - adjustDefaultFlag(yaml, "permissions.default.reserve.", flag, flag.defaultReserve, config.defaultReserveFlags); - } - - transformer.parseXML(MineCity.class.getResourceAsStream("/assets/minecity/messages-en.xml")); - String str = config.locale.toLanguageTag(); - if(!str.equals("en")) - { - try - { - InputStream resource = MineCity.class.getResourceAsStream("/assets/minecity/messages-"+str +".xml"); - if(resource != null) - { - try - { - transformer.parseXML(resource); - } - finally - { - resource.close(); - } - } - else - { - getLogger().log(Level.SEVERE, "There're no translations to "+str+" available."); - str = "en"; - } - } - catch(Exception e) - { - getLogger().log(Level.SEVERE, "Failed to load the "+str+" translations", e); - } - } - final String lang = str; - - config.limits.cities = yaml.getInt("limits.cities", -1); - config.limits.claims = yaml.getInt("limits.claims", -1); - config.limits.islands = yaml.getInt("limits.islands", -1); - - config.costs.cityCreation = yaml.getDouble("costs.city.creation", 1000); - config.costs.islandCreation = yaml.getDouble("costs.island.creation", 500); - config.costs.claim = yaml.getDouble("costs.chunk.claim", 25); - - instance = new MineCityBukkit(this, config, transformer); - instance.mineCity.dataSource.initDB(); - instance.mineCity.commands.parseXml(MineCity.class.getResourceAsStream("/assets/minecity/commands-"+lang+".xml")); - - Set rootCommands = instance.mineCity.commands.getRootCommands(); - try(InputStream is = MineCityPlugin.class.getResourceAsStream("/plugin.yml")) - { - YamlConfiguration plugin = YamlConfiguration.loadConfiguration(new InputStreamReader(is, "UTF-8")); - ConfigurationSection commands = plugin.getConfigurationSection("commands"); - if(commands != null) - { - commands.getKeys(false).stream().filter(key -> !instance.mineCity.commands.get(key).isPresent()) - .forEach(key -> - { - PluginCommand command = getCommand(key); - if(command == null) - return; - - getLogger().info("The command /"+key+" is declared in plugin.yml but is not declared in commands-"+lang+".xml, " + - "trying to unregister it by reflection!" - ); - - try - { - Field field = SimplePluginManager.class.getDeclaredField("commandMap"); - field.setAccessible(true); - SimpleCommandMap commandMap = (SimpleCommandMap) field.get(getServer().getPluginManager()); - if(commandMap == null) - throw new NullPointerException(); - - if(!command.unregister(commandMap)) - throw new IllegalStateException("The command has failed to unregister itself"); - - field = SimpleCommandMap.class.getDeclaredField("knownCommands"); - field.setAccessible(true); - Map knownCommands = (Map) field.get(commandMap); - knownCommands.remove(command.getName()); - knownCommands.remove("minecity:"+command.getName()); - command.getAliases().forEach(s -> {knownCommands.remove("minecity:"+s); knownCommands.remove(s);}); - - getLogger().info("The command /"+key+" was successfully unregistered"); - } - catch(Exception e) - { - getLogger().severe("Failed to unregister the /"+key+" command, it will be present in the game but will do nothing! " - + e.getClass().getSimpleName()+": "+e.getMessage() - ); - } - }); - } - } - - - rootCommands.stream().forEachOrdered(name -> - { - CommandInfo info = instance.mineCity.commands.get(name).get().command; - Command cmd = getCommand(info.getName()); - if(cmd == null) - { - getLogger().info("Unable to register the command /" + info.getName() + - " normally because it's not declared in plugin.yml! Attempting to register using reflections"); - - try - { - Field field = SimplePluginManager.class.getDeclaredField("commandMap"); - field.setAccessible(true); - CommandMap commandMap = (CommandMap) field.get(getServer().getPluginManager()); - ArrayList aliases = new ArrayList<>(info.aliases); - aliases.remove(0); - commandMap.register("minecity", cmd = new Command(name, "", "", aliases) - { - @Override - public boolean execute(CommandSender sender, String commandLabel, String[] args) - { - boolean success; - - if(!isEnabled()) - return false; - - if(!testPermission(sender)) - return true; - - try - { - success = onCommand(sender, this, commandLabel, args); - } - catch (Throwable ex) - { - throw new CommandException("Unhandled exception executing command '"+commandLabel+ - "' in plugin "+MineCityPlugin.this.getDescription().getFullName(), ex - ); - } - - if(!success && usageMessage.length() > 0) - for(String line : usageMessage.replace("", commandLabel).split("\n")) - sender.sendMessage(line); - - return success; - } - }); - - getLogger().info("The command /"+info.getName()+" was successfully registered by reflection"); - } - catch(Exception e) - { - getLogger().severe("Failed to register the command /"+info.getName()+" using reflections. " + - "The command will not be available. "+e.getClass().getSimpleName()+": "+e.getMessage()); - return; - } - } - - cmd.setDescription(info.description); - if(info.args != null && info.args.length > 0) - { - StringBuilder sb = new StringBuilder(); - for(Arg arg : info.args) - { - if(arg.optional()) - sb.append('['); - else - sb.append('<'); - sb.append(instance.mineCity.messageTransformer.toSimpleText(new Message( - "cmd."+info.commandId+".arg."+arg.name().toLowerCase().replaceAll("\\s+","-"), - arg.name() - ))); - if(arg.sticky()) - sb.append("..."); - if(arg.optional()) - sb.append(']'); - else - sb.append('>'); - sb.append(' '); - } - cmd.setUsage(sb.toString()); - } - } - ); - - List worlds = getServer().getWorlds(); - worlds.stream().map(instance::world).forEachOrdered((DBConsumer) instance.mineCity::loadNature); - worlds.stream().map(World::getLoadedChunks).flatMap(Arrays::stream).map(instance::chunk) - .forEachOrdered((DBConsumer< ChunkPos>) instance.mineCity::loadChunk); - - getServer().getOnlinePlayers().forEach(instance::player); - - instance.markEntities(worlds.stream().map(World::getLivingEntities).flatMap(List::stream)); - - reloadTask = getScheduler().runTaskTimerAsynchronously(this, instance.mineCity::reloadQueuedChunk, 1, 1); - playerTick = getScheduler().runTaskTimer(this, ()-> instance.playerMap.values().forEach(BukkitPlayer::tick), 1, 1); - getScheduler().runTaskTimerAsynchronously(this, instance::updateGroups, 1, 1); - } - catch(Exception e) - { - getLogger().log(Level.SEVERE, "Failed to load MineCity, shutting down the server", e); - Bukkit.shutdown(); - } - } - - @Slow - @Override - public void onDisable() - { - instance.loadingTasks.shutdown(); - try - { - instance.loadingTasks.awaitTermination(5, TimeUnit.SECONDS); - } - catch(InterruptedException e) - { - e.printStackTrace(); - try - { - instance.loadingTasks.shutdownNow(); - } - catch(Exception e2) - { - e2.printStackTrace(); - } - } - - try - { - instance.mineCity.dataSource.close(); - } - catch(DataSourceException e) - { - e.printStackTrace(); - } - if(reloadTask != null) - reloadTask.cancel(); - - if(playerTick != null) - playerTick.cancel(); - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) - { - return instance.onCommand(sender, label, args); - } - - @Override - public List onTabComplete(CommandSender sender, Command command, String label, String[] args) - { - String[] path = new String[args.length+1]; - path[0] = label; - System.arraycopy(args, 0, path, 1, args.length); - return instance.mineCity.commands.complete(path); - } - - public BukkitScheduler getScheduler() - { - return getServer().getScheduler(); - } - - public PluginManager getPluginManager() - { - return getServer().getPluginManager(); - } -} +package br.com.gamemods.minecity.bukkit; + +import br.com.gamemods.minecity.MineCity; +import br.com.gamemods.minecity.MineCityConfig; +import br.com.gamemods.minecity.api.Slow; +import br.com.gamemods.minecity.api.command.Arg; +import br.com.gamemods.minecity.api.command.CommandInfo; +import br.com.gamemods.minecity.api.command.LegacyFormat; +import br.com.gamemods.minecity.api.command.Message; +import br.com.gamemods.minecity.api.permission.PermissionFlag; +import br.com.gamemods.minecity.api.permission.SimpleFlagHolder; +import br.com.gamemods.minecity.api.world.ChunkPos; +import br.com.gamemods.minecity.api.world.WorldDim; +import br.com.gamemods.minecity.bukkit.command.BukkitPermission; +import br.com.gamemods.minecity.bukkit.command.BukkitPlayer; +import br.com.gamemods.minecity.datasource.api.DataSourceException; +import br.com.gamemods.minecity.datasource.api.unchecked.DBConsumer; +import br.com.gamemods.minecity.economy.EconomyLayer; +import br.com.gamemods.minecity.permission.PermissionLayer; +import br.com.gamemods.minecity.sponge.SpongeProviders; +import br.com.gamemods.minecity.vault.VaultProviders; +import net.md_5.bungee.api.ChatColor; +import org.bstats.bukkit.Metrics; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.command.*; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.SimplePluginManager; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.scheduler.BukkitTask; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Field; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; + +@SuppressWarnings("CharsetObjectCanBeUsed") +public class MineCityPlugin extends JavaPlugin +{ + private MineCityBukkit instance; + private BukkitTask reloadTask; + private BukkitTask playerTick; + + private void adjustDefaultFlag(FileConfiguration yaml, String prefix, PermissionFlag flag, boolean def, SimpleFlagHolder holder) + { + boolean allow = yaml.getBoolean(prefix+flag+".allow", def); + String msg = yaml.getString(prefix+flag+".message", ""); + + if(!msg.isEmpty()) + holder.getDefaultMessages().put(flag, Message.string(msg)); + + if(!allow) + holder.deny(flag); + } + + @Slow + @Override + public void onEnable() { + try { + Metrics metrics = new Metrics(this, 14222); + } catch (Throwable e) { + getLogger().log(Level.WARNING, "BStats metrics failed to start", e); + } + + PermissionLayer.register("bukkit", BukkitPermission.PROVIDER); + + if (getServer().getPluginManager().isPluginEnabled("Vault")) { + getLogger().info("Vault found. Enabling Vault support"); + EconomyLayer.register("vault", VaultProviders.ECONOMY); + PermissionLayer.register("vault", VaultProviders.PERMISSION); + } + + try { + Class.forName("org.spongepowered.api.Sponge"); + getLogger().info("Sponge API found. Enabling Sponge support"); + EconomyLayer.register("sponge", SpongeProviders.ECONOMY); + PermissionLayer.register("sponge", SpongeProviders.PERMISSION); + } catch (ClassNotFoundException ignored) { + getLogger().info("Sponge API not found, disabling Sponge support"); + } + + BukkitTransformer transformer; + try { + LegacyFormat.BLACK.server = ChatColor.BLACK; + LegacyFormat.DARK_BLUE.server = ChatColor.DARK_BLUE; + LegacyFormat.DARK_GREEN.server = ChatColor.DARK_GREEN; + LegacyFormat.DARK_AQUA.server = ChatColor.DARK_AQUA; + LegacyFormat.DARK_RED.server = ChatColor.DARK_RED; + LegacyFormat.DARK_PURPLE.server = ChatColor.DARK_PURPLE; + LegacyFormat.GOLD.server = ChatColor.GOLD; + LegacyFormat.GRAY.server = ChatColor.GRAY; + LegacyFormat.DARK_GRAY.server = ChatColor.DARK_GRAY; + LegacyFormat.BLUE.server = ChatColor.BLUE; + LegacyFormat.GREEN.server = ChatColor.GREEN; + LegacyFormat.AQUA.server = ChatColor.AQUA; + LegacyFormat.RED.server = ChatColor.RED; + LegacyFormat.LIGHT_PURPLE.server = ChatColor.LIGHT_PURPLE; + LegacyFormat.YELLOW.server = ChatColor.YELLOW; + LegacyFormat.WHITE.server = ChatColor.WHITE; + LegacyFormat.RESET.server = ChatColor.RESET; + LegacyFormat.MAGIC.server = ChatColor.MAGIC; + LegacyFormat.BOLD.server = ChatColor.BOLD; + LegacyFormat.STRIKE.server = ChatColor.STRIKETHROUGH; + LegacyFormat.UNDERLINE.server = ChatColor.UNDERLINE; + LegacyFormat.ITALIC.server = ChatColor.ITALIC; + + transformer = new SpigotTransformer(); + } catch (NoClassDefFoundError ignored) { + transformer = new BukkitTransformer(); + } + + try { + saveDefaultConfig(); + reloadConfig(); + + FileConfiguration yaml = getConfig(); + MineCityConfig config = new MineCityConfig(); + config.dbUrl = yaml.getString("database.url", config.dbUrl); + config.dbUser = Optional.ofNullable(yaml.getString("database.user")).filter(u-> !u.isEmpty()).orElse(null); + config.dbPass = Optional.ofNullable(yaml.getString("database.pass")).filter(p-> !p.isEmpty()).map(String::getBytes).orElse(null); + config.locale = Locale.forLanguageTag(Optional.ofNullable(yaml.getString("language")).filter(l->!l.isEmpty()).orElse("en")); + config.useTitle = yaml.getBoolean("use-titles", true); + config.defaultNatureDisableCities = !yaml.getBoolean("permissions.default.nature.enable-city-creation", true); + config.economy = yaml.getString("economy", "none"); + config.permission = yaml.getString("permission", "bukkit"); + + for (PermissionFlag flag: PermissionFlag.values()) { + adjustDefaultFlag(yaml, "permissions.default.nature.", flag, flag.defaultNature, config.defaultNatureFlags); + adjustDefaultFlag(yaml, "permissions.default.city.", flag, flag.defaultCity, config.defaultCityFlags); + adjustDefaultFlag(yaml, "permissions.default.plot.", flag, flag.defaultPlot, config.defaultPlotFlags); + adjustDefaultFlag(yaml, "permissions.default.reserve.", flag, flag.defaultReserve, config.defaultReserveFlags); + } + + transformer.parseXML(MineCity.class.getResourceAsStream("/assets/minecity/messages-en.xml")); + String str = config.locale.toLanguageTag(); + if (!str.equals("en")) { + try { + InputStream resource = MineCity.class.getResourceAsStream("/assets/minecity/messages-"+str +".xml"); + if (resource != null) { + try { + transformer.parseXML(resource); + } finally { + resource.close(); + } + } else { + getLogger().log(Level.SEVERE, "There're no translations to "+str+" available."); + str = "en"; + } + } + catch (Exception e) { + getLogger().log(Level.SEVERE, "Failed to load the "+str+" translations", e); + } + } + final String lang = str; + + config.limits.cities = yaml.getInt("limits.cities", -1); + config.limits.claims = yaml.getInt("limits.claims", -1); + config.limits.islands = yaml.getInt("limits.islands", -1); + + config.costs.cityCreation = yaml.getDouble("costs.city.creation", 1000); + config.costs.islandCreation = yaml.getDouble("costs.island.creation", 500); + config.costs.claim = yaml.getDouble("costs.chunk.claim", 25); + + instance = new MineCityBukkit(this, config, transformer); + instance.mineCity.dataSource.initDB(); + instance.mineCity.commands.parseXml(MineCity.class.getResourceAsStream("/assets/minecity/commands-"+lang+".xml")); + + Set rootCommands = instance.mineCity.commands.getRootCommands(); + try (InputStream is = MineCityPlugin.class.getResourceAsStream("/plugin.yml")) { + YamlConfiguration plugin = YamlConfiguration.loadConfiguration(new InputStreamReader(is, "UTF-8")); + ConfigurationSection commands = plugin.getConfigurationSection("commands"); + if (commands != null) { + commands.getKeys(false).stream().filter(key -> !instance.mineCity.commands.get(key).isPresent()) + .forEach(key -> + { + PluginCommand command = getCommand(key); + if(command == null) + return; + + getLogger().info("The command /"+key+" is declared in plugin.yml but is not declared in commands-"+lang+".xml, " + + "trying to unregister it by reflection!" + ); + + try + { + Field field = SimplePluginManager.class.getDeclaredField("commandMap"); + field.setAccessible(true); + SimpleCommandMap commandMap = (SimpleCommandMap) field.get(getServer().getPluginManager()); + if(commandMap == null) + throw new NullPointerException(); + + if(!command.unregister(commandMap)) + throw new IllegalStateException("The command has failed to unregister itself"); + + field = SimpleCommandMap.class.getDeclaredField("knownCommands"); + field.setAccessible(true); + Map knownCommands = (Map) field.get(commandMap); + knownCommands.remove(command.getName()); + knownCommands.remove("minecity:"+command.getName()); + command.getAliases().forEach(s -> {knownCommands.remove("minecity:"+s); knownCommands.remove(s);}); + + getLogger().info("The command /"+key+" was successfully unregistered"); + } + catch(Exception e) + { + getLogger().severe("Failed to unregister the /"+key+" command, it will be present in the game but will do nothing! " + + e.getClass().getSimpleName()+": "+e.getMessage() + ); + } + }); + } + } + + + rootCommands.stream().forEachOrdered(name -> + { + CommandInfo info = instance.mineCity.commands.get(name).get().command; + Command cmd = getCommand(info.getName()); + if(cmd == null) + { + getLogger().info("Unable to register the command /" + info.getName() + + " normally because it's not declared in plugin.yml! Attempting to register using reflections"); + + try + { + Field field = SimplePluginManager.class.getDeclaredField("commandMap"); + field.setAccessible(true); + CommandMap commandMap = (CommandMap) field.get(getServer().getPluginManager()); + ArrayList aliases = new ArrayList<>(info.aliases); + aliases.remove(0); + commandMap.register("minecity", cmd = new Command(name, "", "", aliases) + { + @Override + public boolean execute(CommandSender sender, String commandLabel, String[] args) + { + boolean success; + + if(!isEnabled()) + return false; + + if(!testPermission(sender)) + return true; + + try + { + success = onCommand(sender, this, commandLabel, args); + } + catch (Throwable ex) + { + throw new CommandException("Unhandled exception executing command '"+commandLabel+ + "' in plugin "+MineCityPlugin.this.getDescription().getFullName(), ex + ); + } + + if(!success && usageMessage.length() > 0) + for(String line : usageMessage.replace("", commandLabel).split("\n")) + sender.sendMessage(line); + + return success; + } + }); + + getLogger().info("The command /"+info.getName()+" was successfully registered by reflection"); + } + catch(Exception e) + { + getLogger().severe("Failed to register the command /"+info.getName()+" using reflections. " + + "The command will not be available. "+e.getClass().getSimpleName()+": "+e.getMessage()); + return; + } + } + + cmd.setDescription(info.description); + if(info.args != null && info.args.length > 0) + { + StringBuilder sb = new StringBuilder(); + for(Arg arg : info.args) + { + if(arg.optional()) + sb.append('['); + else + sb.append('<'); + sb.append(instance.mineCity.messageTransformer.toSimpleText(new Message( + "cmd."+info.commandId+".arg."+arg.name().toLowerCase().replaceAll("\\s+","-"), + arg.name() + ))); + if(arg.sticky()) + sb.append("..."); + if(arg.optional()) + sb.append(']'); + else + sb.append('>'); + sb.append(' '); + } + cmd.setUsage(sb.toString()); + } + } + ); + + List worlds = getServer().getWorlds(); + worlds.stream().map(instance::world).forEachOrdered((DBConsumer) instance.mineCity::loadNature); + worlds.stream().map(World::getLoadedChunks).flatMap(Arrays::stream).map(instance::chunk) + .forEachOrdered((DBConsumer< ChunkPos>) instance.mineCity::loadChunk); + + getServer().getOnlinePlayers().forEach(instance::player); + + instance.markEntities(worlds.stream().map(World::getLivingEntities).flatMap(List::stream)); + + reloadTask = getScheduler().runTaskTimerAsynchronously(this, instance.mineCity::reloadQueuedChunk, 1, 1); + playerTick = getScheduler().runTaskTimer(this, ()-> instance.playerMap.values().forEach(BukkitPlayer::tick), 1, 1); + getScheduler().runTaskTimerAsynchronously(this, instance::updateGroups, 1, 1); + } + catch(Exception e) + { + getLogger().log(Level.SEVERE, "Failed to load MineCity, shutting down the server", e); + Bukkit.shutdown(); + } + } + + @Slow + @Override + public void onDisable() + { + instance.loadingTasks.shutdown(); + try + { + instance.loadingTasks.awaitTermination(5, TimeUnit.SECONDS); + } + catch(InterruptedException e) + { + e.printStackTrace(); + try + { + instance.loadingTasks.shutdownNow(); + } + catch(Exception e2) + { + e2.printStackTrace(); + } + } + + try + { + instance.mineCity.dataSource.close(); + } + catch(DataSourceException e) + { + e.printStackTrace(); + } + if(reloadTask != null) + reloadTask.cancel(); + + if(playerTick != null) + playerTick.cancel(); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) + { + return instance.onCommand(sender, label, args); + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String label, String[] args) + { + String[] path = new String[args.length+1]; + path[0] = label; + System.arraycopy(args, 0, path, 1, args.length); + return instance.mineCity.commands.complete(path); + } + + public BukkitScheduler getScheduler() + { + return getServer().getScheduler(); + } + + public PluginManager getPluginManager() + { + return getServer().getPluginManager(); + } +} diff --git a/Bukkit/src/main/resources/plugin.yml b/Bukkit/src/main/resources/plugin.yml index 07f3230e..635c3af9 100644 --- a/Bukkit/src/main/resources/plugin.yml +++ b/Bukkit/src/main/resources/plugin.yml @@ -1,786 +1,786 @@ -name: MineCity -version: 1.0.0-SNAPSHOT -main: br.com.gamemods.minecity.bukkit.MineCityPlugin -author: joserobjr -softdepend: [Vault] - -commands: - minecity: - description: All MineCity commands - aliases: [mc] - permission: minecity.cmd.exec - city: - description: All city related commands - aliases: [town,c,t] - permission: minecity.cmd.city.exec - group: - description: All group related commands - permission: minecity.cmd.group.exec - plot: - description: All plot related commands - permission: minecity.cmd.plot.exec - nature: - description: All nature related commands - permission: minecity.cmd.nature.exec - aliases: [world] - -permissions: - # Root commands - minecity.cmd.exec: - description: Gives access to the /minecity command - default: true - minecity.cmd.city.exec: - description: Gives access to the /city command - default: true - minecity.cmd.group.exec: - description: Gives access to the /group command - default: true - minecity.cmd.plot.exec: - description: Gives access to the /plot command - default: true - minecity.cmd.nature.exec: - description: Gives access to the /nature command - default: true - - # Simplified permissions - minecity.admin: - description: Grants all permissions, including permissions to execute administrative commands and all bypasses - children: - minecity.user: true - minecity.bypass: true - minecity.cmd.admin.exec: true - minecity.cmd.reload.exec: true - minecity.cmd.nature.deny: true - minecity.cmd.nature.allow: true - minecity.cmd.auto.claim.exec: true - - minecity.user: - description: Grants basic permissions for normal players - default: true - children: - minecity.cmd.confirm.exec: true - minecity.cmd.help.exec: true - minecity.cmd.city: true - minecity.cmd.group: true - minecity.cmd.plot: true - minecity.cmd.nature.perms: true - - # Bypasses - minecity.bypass: - description: Allows to bypass all bypassable restrictions - children: - minecity.bypass.nature.restriction.city.create: true - - minecity.bypass.nature.restriction.city.create: - description: Allows the player to create cities in worlds where city creations are disabled - default: op - - # Grouped permissions - minecity.cmd.city: - description: Grants all permissions necessary to completely use the /city command as a normal player - children: - minecity.cmd.city.exec: true - minecity.cmd.city.buy: true - minecity.cmd.city.sell: true - minecity.cmd.city.create.exec: true - minecity.cmd.city.claim.exec: true - minecity.cmd.city.disclaim.exec: true - minecity.cmd.city.spawn.exec: true - minecity.cmd.city.rename.exec: true - minecity.cmd.city.transfer.exec: true - minecity.cmd.city.setspawn.exec: true - minecity.cmd.city.map.exec: true - minecity.cmd.city.delete.exec: true - minecity.cmd.city.info.exec: true - minecity.cmd.city.list.exec: true - minecity.cmd.city.perms.exec: true - minecity.cmd.city.perms: true - minecity.cmd.city.deny: true - minecity.cmd.city.allow: true - minecity.cmd.city.clear: true - - minecity.cmd.plot: - description: Grants all permissions necessary to completely use the /plot command as a normal player - children: - minecity.cmd.plot.exec: true - minecity.cmd.plot.buy: true - minecity.cmd.plot.sell: true - minecity.cmd.plot.create.exec: true - minecity.cmd.plot.rename.exec: true - minecity.cmd.plot.return.exec: true - minecity.cmd.plot.transfer.exec: true - minecity.cmd.plot.delete.exec: true - minecity.cmd.plot.info.exec: true - minecity.cmd.plot.readjust.exec: true - minecity.cmd.plot.list.exec: true - minecity.cmd.plot.perms.exec: true - minecity.cmd.plot.perms: true - minecity.cmd.plot.deny: true - minecity.cmd.plot.allow: true - minecity.cmd.plot.clear: true - - minecity.cmd.group: - description: Grants all permissions necessary to completely use the /group command as a normal player - children: - minecity.cmd.group.exec: true - minecity.cmd.group.create.exec: true - minecity.cmd.group.add.exec: true - minecity.cmd.group.remove.exec: true - minecity.cmd.group.list.exec: true - minecity.cmd.group.info.exec: true - minecity.cmd.group.delete.exec: true - minecity.cmd.group.manager: true - - minecity.cmd.group.manager: - children: - minecity.cmd.group.manager.add.exec: true - minecity.cmd.group.manager.remove.exec: true - - - minecity.cmd.city.deny: - children: - minecity.cmd.city.deny.enter.exec: true - minecity.cmd.city.deny.click.exec: true - minecity.cmd.city.deny.pickup.exec: true - minecity.cmd.city.deny.harvest.exec: true - minecity.cmd.city.deny.open.exec: true - minecity.cmd.city.deny.pvp.exec: true - minecity.cmd.city.deny.pvc.exec: true - minecity.cmd.city.deny.modify.exec: true - minecity.cmd.city.deny.vehicle.exec: true - minecity.cmd.city.deny.ride.exec: true - minecity.cmd.city.deny.all: true - - minecity.cmd.city.allow: - children: - minecity.cmd.city.allow.enter.exec: true - minecity.cmd.city.allow.click.exec: true - minecity.cmd.city.allow.pickup.exec: true - minecity.cmd.city.allow.harvest.exec: true - minecity.cmd.city.allow.open.exec: true - minecity.cmd.city.allow.pvp.exec: true - minecity.cmd.city.allow.pvc.exec: true - minecity.cmd.city.allow.modify.exec: true - minecity.cmd.city.allow.vehicle.exec: true - minecity.cmd.city.allow.ride.exec: true - minecity.cmd.city.allow.all: true - - minecity.cmd.city.clear: - children: - minecity.cmd.city.clear.enter.exec: true - minecity.cmd.city.clear.click.exec: true - minecity.cmd.city.clear.pickup.exec: true - minecity.cmd.city.clear.harvest.exec: true - minecity.cmd.city.clear.open.exec: true - minecity.cmd.city.clear.pvp.exec: true - minecity.cmd.city.clear.pvc.exec: true - minecity.cmd.city.clear.modify.exec: true - minecity.cmd.city.clear.vehicle.exec: true - minecity.cmd.city.clear.ride.exec: true - minecity.cmd.city.clear.all: true - - minecity.cmd.city.deny.all: - children: - minecity.cmd.city.deny.all.enter.exec: true - minecity.cmd.city.deny.all.click.exec: true - minecity.cmd.city.deny.all.pickup.exec: true - minecity.cmd.city.deny.all.harvest.exec: true - minecity.cmd.city.deny.all.open.exec: true - minecity.cmd.city.deny.all.pvp.exec: true - minecity.cmd.city.deny.all.pvc.exec: true - minecity.cmd.city.deny.all.modify.exec: true - minecity.cmd.city.deny.all.vehicle.exec: true - minecity.cmd.city.deny.all.ride.exec: true - - minecity.cmd.city.allow.all: - children: - minecity.cmd.city.allow.all.enter.exec: true - minecity.cmd.city.allow.all.click.exec: true - minecity.cmd.city.allow.all.pickup.exec: true - minecity.cmd.city.allow.all.harvest.exec: true - minecity.cmd.city.allow.all.open.exec: true - minecity.cmd.city.allow.all.pvp.exec: true - minecity.cmd.city.allow.all.pvc.exec: true - minecity.cmd.city.allow.all.modify.exec: true - minecity.cmd.city.allow.all.vehicle.exec: true - minecity.cmd.city.allow.all.ride.exec: true - - minecity.cmd.city.clear.all: - children: - minecity.cmd.city.clear.all.enter.exec: true - minecity.cmd.city.clear.all.click.exec: true - minecity.cmd.city.clear.all.pickup.exec: true - minecity.cmd.city.clear.all.harvest.exec: true - minecity.cmd.city.clear.all.open.exec: true - minecity.cmd.city.clear.all.pvp.exec: true - minecity.cmd.city.clear.all.pvc.exec: true - minecity.cmd.city.clear.all.modify.exec: true - minecity.cmd.city.clear.all.vehicle.exec: true - minecity.cmd.city.clear.all.ride.exec: true - - minecity.cmd.city.perms: - children: - minecity.cmd.city.perms.enter.exec: true - minecity.cmd.city.perms.click.exec: true - minecity.cmd.city.perms.pickup.exec: true - minecity.cmd.city.perms.harvest.exec: true - minecity.cmd.city.perms.open.exec: true - minecity.cmd.city.perms.pvp.exec: true - minecity.cmd.city.perms.pvc.exec: true - minecity.cmd.city.perms.modify.exec: true - minecity.cmd.city.perms.vehicle.exec: true - minecity.cmd.city.perms.ride.exec: true - - minecity.cmd.plot.deny: - children: - minecity.cmd.plot.deny.enter.exec: true - minecity.cmd.plot.deny.click.exec: true - minecity.cmd.plot.deny.pickup.exec: true - minecity.cmd.plot.deny.harvest.exec: true - minecity.cmd.plot.deny.open.exec: true - minecity.cmd.plot.deny.pvp.exec: true - minecity.cmd.plot.deny.pvc.exec: true - minecity.cmd.plot.deny.modify.exec: true - minecity.cmd.plot.deny.vehicle.exec: true - minecity.cmd.plot.deny.ride.exec: true - minecity.cmd.plot.deny.all: true - - minecity.cmd.plot.allow: - children: - minecity.cmd.plot.allow.enter.exec: true - minecity.cmd.plot.allow.click.exec: true - minecity.cmd.plot.allow.pickup.exec: true - minecity.cmd.plot.allow.harvest.exec: true - minecity.cmd.plot.allow.open.exec: true - minecity.cmd.plot.allow.pvp.exec: true - minecity.cmd.plot.allow.pvc.exec: true - minecity.cmd.plot.allow.modify.exec: true - minecity.cmd.plot.allow.vehicle.exec: true - minecity.cmd.plot.allow.ride.exec: true - minecity.cmd.plot.allow.all: true - - minecity.cmd.plot.clear: - children: - minecity.cmd.plot.clear.enter.exec: true - minecity.cmd.plot.clear.click.exec: true - minecity.cmd.plot.clear.pickup.exec: true - minecity.cmd.plot.clear.harvest.exec: true - minecity.cmd.plot.clear.open.exec: true - minecity.cmd.plot.clear.pvp.exec: true - minecity.cmd.plot.clear.pvc.exec: true - minecity.cmd.plot.clear.modify.exec: true - minecity.cmd.plot.clear.vehicle.exec: true - minecity.cmd.plot.clear.ride.exec: true - minecity.cmd.plot.clear.all: true - - minecity.cmd.plot.deny.all: - children: - minecity.cmd.plot.deny.all.enter.exec: true - minecity.cmd.plot.deny.all.click.exec: true - minecity.cmd.plot.deny.all.pickup.exec: true - minecity.cmd.plot.deny.all.harvest.exec: true - minecity.cmd.plot.deny.all.open.exec: true - minecity.cmd.plot.deny.all.pvp.exec: true - minecity.cmd.plot.deny.all.pvc.exec: true - minecity.cmd.plot.deny.all.modify.exec: true - minecity.cmd.plot.deny.all.vehicle.exec: true - minecity.cmd.plot.deny.all.ride.exec: true - - minecity.cmd.plot.allow.all: - children: - minecity.cmd.plot.allow.all.enter.exec: true - minecity.cmd.plot.allow.all.click.exec: true - minecity.cmd.plot.allow.all.pickup.exec: true - minecity.cmd.plot.allow.all.harvest.exec: true - minecity.cmd.plot.allow.all.open.exec: true - minecity.cmd.plot.allow.all.pvp.exec: true - minecity.cmd.plot.allow.all.pvc.exec: true - minecity.cmd.plot.allow.all.modify.exec: true - minecity.cmd.plot.allow.all.vehicle.exec: true - minecity.cmd.plot.allow.all.ride.exec: true - - minecity.cmd.plot.clear.all: - children: - minecity.cmd.plot.clear.all.enter.exec: true - minecity.cmd.plot.clear.all.click.exec: true - minecity.cmd.plot.clear.all.pickup.exec: true - minecity.cmd.plot.clear.all.harvest.exec: true - minecity.cmd.plot.clear.all.open.exec: true - minecity.cmd.plot.clear.all.pvp.exec: true - minecity.cmd.plot.clear.all.pvc.exec: true - minecity.cmd.plot.clear.all.modify.exec: true - minecity.cmd.plot.clear.all.vehicle.exec: true - minecity.cmd.plot.clear.all.ride.exec: true - - minecity.cmd.plot.perms: - children: - minecity.cmd.plot.perms.enter.exec: true - minecity.cmd.plot.perms.click.exec: true - minecity.cmd.plot.perms.pickup.exec: true - minecity.cmd.plot.perms.harvest.exec: true - minecity.cmd.plot.perms.open.exec: true - minecity.cmd.plot.perms.pvp.exec: true - minecity.cmd.plot.perms.pvc.exec: true - minecity.cmd.plot.perms.modify.exec: true - minecity.cmd.plot.perms.vehicle.exec: true - minecity.cmd.plot.perms.ride.exec: true - - minecity.cmd.nature.deny: - children: - minecity.cmd.nature.deny.enter.exec: true - minecity.cmd.nature.deny.click.exec: true - minecity.cmd.nature.deny.pickup.exec: true - minecity.cmd.nature.deny.harvest.exec: true - minecity.cmd.nature.deny.open.exec: true - minecity.cmd.nature.deny.pvp.exec: true - minecity.cmd.nature.deny.pvc.exec: true - minecity.cmd.nature.deny.modify.exec: true - minecity.cmd.nature.deny.vehicle.exec: true - minecity.cmd.nature.deny.ride.exec: true - - minecity.cmd.nature.allow: - children: - minecity.cmd.nature.allow.enter.exec: true - minecity.cmd.nature.allow.click.exec: true - minecity.cmd.nature.allow.pickup.exec: true - minecity.cmd.nature.allow.harvest.exec: true - minecity.cmd.nature.allow.open.exec: true - minecity.cmd.nature.allow.pvp.exec: true - minecity.cmd.nature.allow.pvc.exec: true - minecity.cmd.nature.allow.modify.exec: true - minecity.cmd.nature.allow.vehicle.exec: true - minecity.cmd.nature.allow.ride.exec: true - - minecity.cmd.nature.perms: - children: - minecity.cmd.nature.perms.exec: true - minecity.cmd.nature.perms.enter.exec: true - minecity.cmd.nature.perms.click.exec: true - minecity.cmd.nature.perms.pickup.exec: true - minecity.cmd.nature.perms.harvest.exec: true - minecity.cmd.nature.perms.open.exec: true - minecity.cmd.nature.perms.pvp.exec: true - minecity.cmd.nature.perms.pvc.exec: true - minecity.cmd.nature.perms.modify.exec: true - minecity.cmd.nature.perms.vehicle.exec: true - minecity.cmd.nature.perms.ride.exec: true - - # Command Functions - minecity.cmd.admin.exec: - default: op - minecity.cmd.nature.deny.enter.exec: - default: op - minecity.cmd.nature.deny.click.exec: - default: op - minecity.cmd.nature.deny.pickup.exec: - default: op - minecity.cmd.nature.deny.harvest.exec: - default: op - minecity.cmd.nature.deny.open.exec: - default: op - minecity.cmd.nature.deny.pvp.exec: - default: op - minecity.cmd.nature.deny.pvc.exec: - default: op - minecity.cmd.nature.deny.modify.exec: - default: op - minecity.cmd.nature.deny.vehicle.exec: - default: op - minecity.cmd.nature.deny.ride.exec: - default: op - minecity.cmd.nature.allow.enter.exec: - default: op - minecity.cmd.nature.allow.click.exec: - default: op - minecity.cmd.nature.allow.pickup.exec: - default: op - minecity.cmd.nature.allow.harvest.exec: - default: op - minecity.cmd.nature.allow.open.exec: - default: op - minecity.cmd.nature.allow.pvp.exec: - default: op - minecity.cmd.nature.allow.pvc.exec: - default: op - minecity.cmd.nature.allow.modify.exec: - default: op - minecity.cmd.nature.allow.vehicle.exec: - default: op - minecity.cmd.nature.allow.ride.exec: - default: op - minecity.cmd.nature.perms.enter.exec: - default: op - minecity.cmd.nature.perms.click.exec: - default: op - minecity.cmd.nature.perms.pickup.exec: - default: op - minecity.cmd.nature.perms.harvest.exec: - default: op - minecity.cmd.nature.perms.open.exec: - default: op - minecity.cmd.nature.perms.pvp.exec: - default: op - minecity.cmd.nature.perms.pvc.exec: - default: op - minecity.cmd.nature.perms.modify.exec: - default: op - minecity.cmd.nature.perms.vehicle.exec: - default: op - minecity.cmd.nature.perms.ride.exec: - default: op - minecity.cmd.nature.perms.exec: - default: op - minecity.cmd.city.create.exec: - default: op - minecity.cmd.city.claim.exec: - default: op - minecity.cmd.city.disclaim.exec: - default: op - minecity.cmd.city.spawn.exec: - default: op - minecity.cmd.city.rename.exec: - default: op - minecity.cmd.city.transfer.exec: - default: op - minecity.cmd.city.setspawn.exec: - default: op - minecity.cmd.city.map.exec: - default: op - minecity.cmd.city.delete.exec: - default: op - minecity.cmd.city.info.exec: - default: op - minecity.cmd.city.deny.enter.exec: - default: op - minecity.cmd.city.deny.click.exec: - default: op - minecity.cmd.city.deny.pickup.exec: - default: op - minecity.cmd.city.deny.harvest.exec: - default: op - minecity.cmd.city.deny.open.exec: - default: op - minecity.cmd.city.deny.pvp.exec: - default: op - minecity.cmd.city.deny.pvc.exec: - default: op - minecity.cmd.city.deny.modify.exec: - default: op - minecity.cmd.city.deny.vehicle.exec: - default: op - minecity.cmd.city.deny.ride.exec: - default: op - minecity.cmd.city.allow.enter.exec: - default: op - minecity.cmd.city.allow.click.exec: - default: op - minecity.cmd.city.allow.pickup.exec: - default: op - minecity.cmd.city.allow.harvest.exec: - default: op - minecity.cmd.city.allow.open.exec: - default: op - minecity.cmd.city.allow.pvp.exec: - default: op - minecity.cmd.city.allow.pvc.exec: - default: op - minecity.cmd.city.allow.modify.exec: - default: op - minecity.cmd.city.allow.vehicle.exec: - default: op - minecity.cmd.city.allow.ride.exec: - default: op - minecity.cmd.city.clear.enter.exec: - default: op - minecity.cmd.city.clear.click.exec: - default: op - minecity.cmd.city.clear.pickup.exec: - default: op - minecity.cmd.city.clear.harvest.exec: - default: op - minecity.cmd.city.clear.open.exec: - default: op - minecity.cmd.city.clear.pvp.exec: - default: op - minecity.cmd.city.clear.pvc.exec: - default: op - minecity.cmd.city.clear.modify.exec: - default: op - minecity.cmd.city.clear.vehicle.exec: - default: op - minecity.cmd.city.clear.ride.exec: - default: op - minecity.cmd.city.deny.all.enter.exec: - default: op - minecity.cmd.city.deny.all.click.exec: - default: op - minecity.cmd.city.deny.all.pickup.exec: - default: op - minecity.cmd.city.deny.all.harvest.exec: - default: op - minecity.cmd.city.deny.all.open.exec: - default: op - minecity.cmd.city.deny.all.pvp.exec: - default: op - minecity.cmd.city.deny.all.pvc.exec: - default: op - minecity.cmd.city.deny.all.modify.exec: - default: op - minecity.cmd.city.deny.all.vehicle.exec: - default: op - minecity.cmd.city.deny.all.ride.exec: - default: op - minecity.cmd.city.allow.all.enter.exec: - default: op - minecity.cmd.city.allow.all.click.exec: - default: op - minecity.cmd.city.allow.all.pickup.exec: - default: op - minecity.cmd.city.allow.all.harvest.exec: - default: op - minecity.cmd.city.allow.all.open.exec: - default: op - minecity.cmd.city.allow.all.pvp.exec: - default: op - minecity.cmd.city.allow.all.pvc.exec: - default: op - minecity.cmd.city.allow.all.modify.exec: - default: op - minecity.cmd.city.allow.all.vehicle.exec: - default: op - minecity.cmd.city.allow.all.ride.exec: - default: op - minecity.cmd.city.clear.all.enter.exec: - default: op - minecity.cmd.city.clear.all.click.exec: - default: op - minecity.cmd.city.clear.all.pickup.exec: - default: op - minecity.cmd.city.clear.all.harvest.exec: - default: op - minecity.cmd.city.clear.all.open.exec: - default: op - minecity.cmd.city.clear.all.pvp.exec: - default: op - minecity.cmd.city.clear.all.pvc.exec: - default: op - minecity.cmd.city.clear.all.modify.exec: - default: op - minecity.cmd.city.clear.all.vehicle.exec: - default: op - minecity.cmd.city.clear.all.ride.exec: - default: op - minecity.cmd.plot.deny.enter.exec: - default: op - minecity.cmd.plot.deny.click.exec: - default: op - minecity.cmd.plot.deny.pickup.exec: - default: op - minecity.cmd.plot.deny.harvest.exec: - default: op - minecity.cmd.plot.deny.open.exec: - default: op - minecity.cmd.plot.deny.pvp.exec: - default: op - minecity.cmd.plot.deny.pvc.exec: - default: op - minecity.cmd.plot.deny.modify.exec: - default: op - minecity.cmd.plot.deny.vehicle.exec: - default: op - minecity.cmd.plot.deny.ride.exec: - default: op - minecity.cmd.plot.allow.enter.exec: - default: op - minecity.cmd.plot.allow.click.exec: - default: op - minecity.cmd.plot.allow.pickup.exec: - default: op - minecity.cmd.plot.allow.harvest.exec: - default: op - minecity.cmd.plot.allow.open.exec: - default: op - minecity.cmd.plot.allow.pvp.exec: - default: op - minecity.cmd.plot.allow.pvc.exec: - default: op - minecity.cmd.plot.allow.modify.exec: - default: op - minecity.cmd.plot.allow.vehicle.exec: - default: op - minecity.cmd.plot.allow.ride.exec: - default: op - minecity.cmd.plot.clear.enter.exec: - default: op - minecity.cmd.plot.clear.click.exec: - default: op - minecity.cmd.plot.clear.pickup.exec: - default: op - minecity.cmd.plot.clear.harvest.exec: - default: op - minecity.cmd.plot.clear.open.exec: - default: op - minecity.cmd.plot.clear.pvp.exec: - default: op - minecity.cmd.plot.clear.pvc.exec: - default: op - minecity.cmd.plot.clear.modify.exec: - default: op - minecity.cmd.plot.clear.vehicle.exec: - default: op - minecity.cmd.plot.clear.ride.exec: - default: op - minecity.cmd.plot.deny.all.enter.exec: - default: op - minecity.cmd.plot.deny.all.click.exec: - default: op - minecity.cmd.plot.deny.all.pickup.exec: - default: op - minecity.cmd.plot.deny.all.harvest.exec: - default: op - minecity.cmd.plot.deny.all.open.exec: - default: op - minecity.cmd.plot.deny.all.pvp.exec: - default: op - minecity.cmd.plot.deny.all.pvc.exec: - default: op - minecity.cmd.plot.deny.all.modify.exec: - default: op - minecity.cmd.plot.deny.all.vehicle.exec: - default: op - minecity.cmd.plot.deny.all.ride.exec: - default: op - minecity.cmd.plot.allow.all.enter.exec: - default: op - minecity.cmd.plot.allow.all.click.exec: - default: op - minecity.cmd.plot.allow.all.pickup.exec: - default: op - minecity.cmd.plot.allow.all.harvest.exec: - default: op - minecity.cmd.plot.allow.all.open.exec: - default: op - minecity.cmd.plot.allow.all.pvp.exec: - default: op - minecity.cmd.plot.allow.all.pvc.exec: - default: op - minecity.cmd.plot.allow.all.modify.exec: - default: op - minecity.cmd.plot.allow.all.vehicle.exec: - default: op - minecity.cmd.plot.allow.all.ride.exec: - default: op - minecity.cmd.plot.clear.all.enter.exec: - default: op - minecity.cmd.plot.clear.all.click.exec: - default: op - minecity.cmd.plot.clear.all.pickup.exec: - default: op - minecity.cmd.plot.clear.all.harvest.exec: - default: op - minecity.cmd.plot.clear.all.open.exec: - default: op - minecity.cmd.plot.clear.all.pvp.exec: - default: op - minecity.cmd.plot.clear.all.pvc.exec: - default: op - minecity.cmd.plot.clear.all.modify.exec: - default: op - minecity.cmd.plot.clear.all.vehicle.exec: - default: op - minecity.cmd.plot.clear.all.ride.exec: - default: op - minecity.cmd.plot.perms.enter.exec: - default: op - minecity.cmd.plot.perms.click.exec: - default: op - minecity.cmd.plot.perms.pickup.exec: - default: op - minecity.cmd.plot.perms.harvest.exec: - default: op - minecity.cmd.plot.perms.open.exec: - default: op - minecity.cmd.plot.perms.pvp.exec: - default: op - minecity.cmd.plot.perms.pvc.exec: - default: op - minecity.cmd.plot.perms.modify.exec: - default: op - minecity.cmd.plot.perms.vehicle.exec: - default: op - minecity.cmd.plot.perms.ride.exec: - default: op - minecity.cmd.plot.perms.exec: - default: op - minecity.cmd.city.perms.enter.exec: - default: op - minecity.cmd.city.perms.click.exec: - default: op - minecity.cmd.city.perms.pickup.exec: - default: op - minecity.cmd.city.perms.harvest.exec: - default: op - minecity.cmd.city.perms.open.exec: - default: op - minecity.cmd.city.perms.pvp.exec: - default: op - minecity.cmd.city.perms.pvc.exec: - default: op - minecity.cmd.city.perms.modify.exec: - default: op - minecity.cmd.city.perms.vehicle.exec: - default: op - minecity.cmd.city.perms.ride.exec: - default: op - minecity.cmd.city.perms.exec: - default: op - minecity.cmd.city.sell.exec: - default: op - minecity.cmd.city.buy.exec: - default: op - minecity.cmd.auto.claim.exec: - default: op - minecity.cmd.group.create.exec: - default: op - minecity.cmd.group.add.exec: - default: op - minecity.cmd.group.remove.exec: - default: op - minecity.cmd.group.list.exec: - default: op - minecity.cmd.group.info.exec: - default: op - minecity.cmd.group.delete.exec: - default: op - minecity.cmd.group.add.manager.exec: - default: op - minecity.cmd.group.remove.manager.exec: - default: op - minecity.cmd.confirm.exec: - default: op - minecity.cmd.help.exec: - default: op - minecity.cmd.reload.exec: - default: op - minecity.cmd.plot.create.exec: - default: op - minecity.cmd.plot.rename.exec: - default: op - minecity.cmd.plot.return.exec: - default: op - minecity.cmd.plot.transfer.exec: - default: op - minecity.cmd.plot.delete.exec: - default: op - minecity.cmd.plot.info.exec: - default: op - minecity.cmd.plot.readjust.exec: - default: op - minecity.cmd.city.list.exec: - default: op - minecity.cmd.plot.list.exec: - default: op - minecity.cmd.plot.sell.exec: - default: op - minecity.cmd.plot.buy.exec: - default: op +name: MineCity +version: 1.0.0-SNAPSHOT +main: br.com.gamemods.minecity.bukkit.MineCityPlugin +author: joserobjr +softdepend: [Vault] + +commands: + minecity: + description: All MineCity commands + aliases: [mc] + permission: minecity.cmd.exec + city: + description: All city related commands + aliases: [town,c,t] + permission: minecity.cmd.city.exec + group: + description: All group related commands + permission: minecity.cmd.group.exec + plot: + description: All plot related commands + permission: minecity.cmd.plot.exec + nature: + description: All nature related commands + permission: minecity.cmd.nature.exec + aliases: [world] + +permissions: + # Root commands + minecity.cmd.exec: + description: Gives access to the /minecity command + default: true + minecity.cmd.city.exec: + description: Gives access to the /city command + default: true + minecity.cmd.group.exec: + description: Gives access to the /group command + default: true + minecity.cmd.plot.exec: + description: Gives access to the /plot command + default: true + minecity.cmd.nature.exec: + description: Gives access to the /nature command + default: true + + # Simplified permissions + minecity.admin: + description: Grants all permissions, including permissions to execute administrative commands and all bypasses + children: + minecity.user: true + minecity.bypass: true + minecity.cmd.admin.exec: true + minecity.cmd.reload.exec: true + minecity.cmd.nature.deny: true + minecity.cmd.nature.allow: true + minecity.cmd.auto.claim.exec: true + + minecity.user: + description: Grants basic permissions for normal players + default: true + children: + minecity.cmd.confirm.exec: true + minecity.cmd.help.exec: true + minecity.cmd.city: true + minecity.cmd.group: true + minecity.cmd.plot: true + minecity.cmd.nature.perms: true + + # Bypasses + minecity.bypass: + description: Allows to bypass all bypassable restrictions + children: + minecity.bypass.nature.restriction.city.create: true + + minecity.bypass.nature.restriction.city.create: + description: Allows the player to create cities in worlds where city creations are disabled + default: op + + # Grouped permissions + minecity.cmd.city: + description: Grants all permissions necessary to completely use the /city command as a normal player + children: + minecity.cmd.city.exec: true + minecity.cmd.city.buy: true + minecity.cmd.city.sell: true + minecity.cmd.city.create.exec: true + minecity.cmd.city.claim.exec: true + minecity.cmd.city.disclaim.exec: true + minecity.cmd.city.spawn.exec: true + minecity.cmd.city.rename.exec: true + minecity.cmd.city.transfer.exec: true + minecity.cmd.city.setspawn.exec: true + minecity.cmd.city.map.exec: true + minecity.cmd.city.delete.exec: true + minecity.cmd.city.info.exec: true + minecity.cmd.city.list.exec: true + minecity.cmd.city.perms.exec: true + minecity.cmd.city.perms: true + minecity.cmd.city.deny: true + minecity.cmd.city.allow: true + minecity.cmd.city.clear: true + + minecity.cmd.plot: + description: Grants all permissions necessary to completely use the /plot command as a normal player + children: + minecity.cmd.plot.exec: true + minecity.cmd.plot.buy: true + minecity.cmd.plot.sell: true + minecity.cmd.plot.create.exec: true + minecity.cmd.plot.rename.exec: true + minecity.cmd.plot.return.exec: true + minecity.cmd.plot.transfer.exec: true + minecity.cmd.plot.delete.exec: true + minecity.cmd.plot.info.exec: true + minecity.cmd.plot.readjust.exec: true + minecity.cmd.plot.list.exec: true + minecity.cmd.plot.perms.exec: true + minecity.cmd.plot.perms: true + minecity.cmd.plot.deny: true + minecity.cmd.plot.allow: true + minecity.cmd.plot.clear: true + + minecity.cmd.group: + description: Grants all permissions necessary to completely use the /group command as a normal player + children: + minecity.cmd.group.exec: true + minecity.cmd.group.create.exec: true + minecity.cmd.group.add.exec: true + minecity.cmd.group.remove.exec: true + minecity.cmd.group.list.exec: true + minecity.cmd.group.info.exec: true + minecity.cmd.group.delete.exec: true + minecity.cmd.group.manager: true + + minecity.cmd.group.manager: + children: + minecity.cmd.group.manager.add.exec: true + minecity.cmd.group.manager.remove.exec: true + + + minecity.cmd.city.deny: + children: + minecity.cmd.city.deny.enter.exec: true + minecity.cmd.city.deny.click.exec: true + minecity.cmd.city.deny.pickup.exec: true + minecity.cmd.city.deny.harvest.exec: true + minecity.cmd.city.deny.open.exec: true + minecity.cmd.city.deny.pvp.exec: true + minecity.cmd.city.deny.pvc.exec: true + minecity.cmd.city.deny.modify.exec: true + minecity.cmd.city.deny.vehicle.exec: true + minecity.cmd.city.deny.ride.exec: true + minecity.cmd.city.deny.all: true + + minecity.cmd.city.allow: + children: + minecity.cmd.city.allow.enter.exec: true + minecity.cmd.city.allow.click.exec: true + minecity.cmd.city.allow.pickup.exec: true + minecity.cmd.city.allow.harvest.exec: true + minecity.cmd.city.allow.open.exec: true + minecity.cmd.city.allow.pvp.exec: true + minecity.cmd.city.allow.pvc.exec: true + minecity.cmd.city.allow.modify.exec: true + minecity.cmd.city.allow.vehicle.exec: true + minecity.cmd.city.allow.ride.exec: true + minecity.cmd.city.allow.all: true + + minecity.cmd.city.clear: + children: + minecity.cmd.city.clear.enter.exec: true + minecity.cmd.city.clear.click.exec: true + minecity.cmd.city.clear.pickup.exec: true + minecity.cmd.city.clear.harvest.exec: true + minecity.cmd.city.clear.open.exec: true + minecity.cmd.city.clear.pvp.exec: true + minecity.cmd.city.clear.pvc.exec: true + minecity.cmd.city.clear.modify.exec: true + minecity.cmd.city.clear.vehicle.exec: true + minecity.cmd.city.clear.ride.exec: true + minecity.cmd.city.clear.all: true + + minecity.cmd.city.deny.all: + children: + minecity.cmd.city.deny.all.enter.exec: true + minecity.cmd.city.deny.all.click.exec: true + minecity.cmd.city.deny.all.pickup.exec: true + minecity.cmd.city.deny.all.harvest.exec: true + minecity.cmd.city.deny.all.open.exec: true + minecity.cmd.city.deny.all.pvp.exec: true + minecity.cmd.city.deny.all.pvc.exec: true + minecity.cmd.city.deny.all.modify.exec: true + minecity.cmd.city.deny.all.vehicle.exec: true + minecity.cmd.city.deny.all.ride.exec: true + + minecity.cmd.city.allow.all: + children: + minecity.cmd.city.allow.all.enter.exec: true + minecity.cmd.city.allow.all.click.exec: true + minecity.cmd.city.allow.all.pickup.exec: true + minecity.cmd.city.allow.all.harvest.exec: true + minecity.cmd.city.allow.all.open.exec: true + minecity.cmd.city.allow.all.pvp.exec: true + minecity.cmd.city.allow.all.pvc.exec: true + minecity.cmd.city.allow.all.modify.exec: true + minecity.cmd.city.allow.all.vehicle.exec: true + minecity.cmd.city.allow.all.ride.exec: true + + minecity.cmd.city.clear.all: + children: + minecity.cmd.city.clear.all.enter.exec: true + minecity.cmd.city.clear.all.click.exec: true + minecity.cmd.city.clear.all.pickup.exec: true + minecity.cmd.city.clear.all.harvest.exec: true + minecity.cmd.city.clear.all.open.exec: true + minecity.cmd.city.clear.all.pvp.exec: true + minecity.cmd.city.clear.all.pvc.exec: true + minecity.cmd.city.clear.all.modify.exec: true + minecity.cmd.city.clear.all.vehicle.exec: true + minecity.cmd.city.clear.all.ride.exec: true + + minecity.cmd.city.perms: + children: + minecity.cmd.city.perms.enter.exec: true + minecity.cmd.city.perms.click.exec: true + minecity.cmd.city.perms.pickup.exec: true + minecity.cmd.city.perms.harvest.exec: true + minecity.cmd.city.perms.open.exec: true + minecity.cmd.city.perms.pvp.exec: true + minecity.cmd.city.perms.pvc.exec: true + minecity.cmd.city.perms.modify.exec: true + minecity.cmd.city.perms.vehicle.exec: true + minecity.cmd.city.perms.ride.exec: true + + minecity.cmd.plot.deny: + children: + minecity.cmd.plot.deny.enter.exec: true + minecity.cmd.plot.deny.click.exec: true + minecity.cmd.plot.deny.pickup.exec: true + minecity.cmd.plot.deny.harvest.exec: true + minecity.cmd.plot.deny.open.exec: true + minecity.cmd.plot.deny.pvp.exec: true + minecity.cmd.plot.deny.pvc.exec: true + minecity.cmd.plot.deny.modify.exec: true + minecity.cmd.plot.deny.vehicle.exec: true + minecity.cmd.plot.deny.ride.exec: true + minecity.cmd.plot.deny.all: true + + minecity.cmd.plot.allow: + children: + minecity.cmd.plot.allow.enter.exec: true + minecity.cmd.plot.allow.click.exec: true + minecity.cmd.plot.allow.pickup.exec: true + minecity.cmd.plot.allow.harvest.exec: true + minecity.cmd.plot.allow.open.exec: true + minecity.cmd.plot.allow.pvp.exec: true + minecity.cmd.plot.allow.pvc.exec: true + minecity.cmd.plot.allow.modify.exec: true + minecity.cmd.plot.allow.vehicle.exec: true + minecity.cmd.plot.allow.ride.exec: true + minecity.cmd.plot.allow.all: true + + minecity.cmd.plot.clear: + children: + minecity.cmd.plot.clear.enter.exec: true + minecity.cmd.plot.clear.click.exec: true + minecity.cmd.plot.clear.pickup.exec: true + minecity.cmd.plot.clear.harvest.exec: true + minecity.cmd.plot.clear.open.exec: true + minecity.cmd.plot.clear.pvp.exec: true + minecity.cmd.plot.clear.pvc.exec: true + minecity.cmd.plot.clear.modify.exec: true + minecity.cmd.plot.clear.vehicle.exec: true + minecity.cmd.plot.clear.ride.exec: true + minecity.cmd.plot.clear.all: true + + minecity.cmd.plot.deny.all: + children: + minecity.cmd.plot.deny.all.enter.exec: true + minecity.cmd.plot.deny.all.click.exec: true + minecity.cmd.plot.deny.all.pickup.exec: true + minecity.cmd.plot.deny.all.harvest.exec: true + minecity.cmd.plot.deny.all.open.exec: true + minecity.cmd.plot.deny.all.pvp.exec: true + minecity.cmd.plot.deny.all.pvc.exec: true + minecity.cmd.plot.deny.all.modify.exec: true + minecity.cmd.plot.deny.all.vehicle.exec: true + minecity.cmd.plot.deny.all.ride.exec: true + + minecity.cmd.plot.allow.all: + children: + minecity.cmd.plot.allow.all.enter.exec: true + minecity.cmd.plot.allow.all.click.exec: true + minecity.cmd.plot.allow.all.pickup.exec: true + minecity.cmd.plot.allow.all.harvest.exec: true + minecity.cmd.plot.allow.all.open.exec: true + minecity.cmd.plot.allow.all.pvp.exec: true + minecity.cmd.plot.allow.all.pvc.exec: true + minecity.cmd.plot.allow.all.modify.exec: true + minecity.cmd.plot.allow.all.vehicle.exec: true + minecity.cmd.plot.allow.all.ride.exec: true + + minecity.cmd.plot.clear.all: + children: + minecity.cmd.plot.clear.all.enter.exec: true + minecity.cmd.plot.clear.all.click.exec: true + minecity.cmd.plot.clear.all.pickup.exec: true + minecity.cmd.plot.clear.all.harvest.exec: true + minecity.cmd.plot.clear.all.open.exec: true + minecity.cmd.plot.clear.all.pvp.exec: true + minecity.cmd.plot.clear.all.pvc.exec: true + minecity.cmd.plot.clear.all.modify.exec: true + minecity.cmd.plot.clear.all.vehicle.exec: true + minecity.cmd.plot.clear.all.ride.exec: true + + minecity.cmd.plot.perms: + children: + minecity.cmd.plot.perms.enter.exec: true + minecity.cmd.plot.perms.click.exec: true + minecity.cmd.plot.perms.pickup.exec: true + minecity.cmd.plot.perms.harvest.exec: true + minecity.cmd.plot.perms.open.exec: true + minecity.cmd.plot.perms.pvp.exec: true + minecity.cmd.plot.perms.pvc.exec: true + minecity.cmd.plot.perms.modify.exec: true + minecity.cmd.plot.perms.vehicle.exec: true + minecity.cmd.plot.perms.ride.exec: true + + minecity.cmd.nature.deny: + children: + minecity.cmd.nature.deny.enter.exec: true + minecity.cmd.nature.deny.click.exec: true + minecity.cmd.nature.deny.pickup.exec: true + minecity.cmd.nature.deny.harvest.exec: true + minecity.cmd.nature.deny.open.exec: true + minecity.cmd.nature.deny.pvp.exec: true + minecity.cmd.nature.deny.pvc.exec: true + minecity.cmd.nature.deny.modify.exec: true + minecity.cmd.nature.deny.vehicle.exec: true + minecity.cmd.nature.deny.ride.exec: true + + minecity.cmd.nature.allow: + children: + minecity.cmd.nature.allow.enter.exec: true + minecity.cmd.nature.allow.click.exec: true + minecity.cmd.nature.allow.pickup.exec: true + minecity.cmd.nature.allow.harvest.exec: true + minecity.cmd.nature.allow.open.exec: true + minecity.cmd.nature.allow.pvp.exec: true + minecity.cmd.nature.allow.pvc.exec: true + minecity.cmd.nature.allow.modify.exec: true + minecity.cmd.nature.allow.vehicle.exec: true + minecity.cmd.nature.allow.ride.exec: true + + minecity.cmd.nature.perms: + children: + minecity.cmd.nature.perms.exec: true + minecity.cmd.nature.perms.enter.exec: true + minecity.cmd.nature.perms.click.exec: true + minecity.cmd.nature.perms.pickup.exec: true + minecity.cmd.nature.perms.harvest.exec: true + minecity.cmd.nature.perms.open.exec: true + minecity.cmd.nature.perms.pvp.exec: true + minecity.cmd.nature.perms.pvc.exec: true + minecity.cmd.nature.perms.modify.exec: true + minecity.cmd.nature.perms.vehicle.exec: true + minecity.cmd.nature.perms.ride.exec: true + + # Command Functions + minecity.cmd.admin.exec: + default: op + minecity.cmd.nature.deny.enter.exec: + default: op + minecity.cmd.nature.deny.click.exec: + default: op + minecity.cmd.nature.deny.pickup.exec: + default: op + minecity.cmd.nature.deny.harvest.exec: + default: op + minecity.cmd.nature.deny.open.exec: + default: op + minecity.cmd.nature.deny.pvp.exec: + default: op + minecity.cmd.nature.deny.pvc.exec: + default: op + minecity.cmd.nature.deny.modify.exec: + default: op + minecity.cmd.nature.deny.vehicle.exec: + default: op + minecity.cmd.nature.deny.ride.exec: + default: op + minecity.cmd.nature.allow.enter.exec: + default: op + minecity.cmd.nature.allow.click.exec: + default: op + minecity.cmd.nature.allow.pickup.exec: + default: op + minecity.cmd.nature.allow.harvest.exec: + default: op + minecity.cmd.nature.allow.open.exec: + default: op + minecity.cmd.nature.allow.pvp.exec: + default: op + minecity.cmd.nature.allow.pvc.exec: + default: op + minecity.cmd.nature.allow.modify.exec: + default: op + minecity.cmd.nature.allow.vehicle.exec: + default: op + minecity.cmd.nature.allow.ride.exec: + default: op + minecity.cmd.nature.perms.enter.exec: + default: op + minecity.cmd.nature.perms.click.exec: + default: op + minecity.cmd.nature.perms.pickup.exec: + default: op + minecity.cmd.nature.perms.harvest.exec: + default: op + minecity.cmd.nature.perms.open.exec: + default: op + minecity.cmd.nature.perms.pvp.exec: + default: op + minecity.cmd.nature.perms.pvc.exec: + default: op + minecity.cmd.nature.perms.modify.exec: + default: op + minecity.cmd.nature.perms.vehicle.exec: + default: op + minecity.cmd.nature.perms.ride.exec: + default: op + minecity.cmd.nature.perms.exec: + default: op + minecity.cmd.city.create.exec: + default: op + minecity.cmd.city.claim.exec: + default: op + minecity.cmd.city.disclaim.exec: + default: op + minecity.cmd.city.spawn.exec: + default: op + minecity.cmd.city.rename.exec: + default: op + minecity.cmd.city.transfer.exec: + default: op + minecity.cmd.city.setspawn.exec: + default: op + minecity.cmd.city.map.exec: + default: op + minecity.cmd.city.delete.exec: + default: op + minecity.cmd.city.info.exec: + default: op + minecity.cmd.city.deny.enter.exec: + default: op + minecity.cmd.city.deny.click.exec: + default: op + minecity.cmd.city.deny.pickup.exec: + default: op + minecity.cmd.city.deny.harvest.exec: + default: op + minecity.cmd.city.deny.open.exec: + default: op + minecity.cmd.city.deny.pvp.exec: + default: op + minecity.cmd.city.deny.pvc.exec: + default: op + minecity.cmd.city.deny.modify.exec: + default: op + minecity.cmd.city.deny.vehicle.exec: + default: op + minecity.cmd.city.deny.ride.exec: + default: op + minecity.cmd.city.allow.enter.exec: + default: op + minecity.cmd.city.allow.click.exec: + default: op + minecity.cmd.city.allow.pickup.exec: + default: op + minecity.cmd.city.allow.harvest.exec: + default: op + minecity.cmd.city.allow.open.exec: + default: op + minecity.cmd.city.allow.pvp.exec: + default: op + minecity.cmd.city.allow.pvc.exec: + default: op + minecity.cmd.city.allow.modify.exec: + default: op + minecity.cmd.city.allow.vehicle.exec: + default: op + minecity.cmd.city.allow.ride.exec: + default: op + minecity.cmd.city.clear.enter.exec: + default: op + minecity.cmd.city.clear.click.exec: + default: op + minecity.cmd.city.clear.pickup.exec: + default: op + minecity.cmd.city.clear.harvest.exec: + default: op + minecity.cmd.city.clear.open.exec: + default: op + minecity.cmd.city.clear.pvp.exec: + default: op + minecity.cmd.city.clear.pvc.exec: + default: op + minecity.cmd.city.clear.modify.exec: + default: op + minecity.cmd.city.clear.vehicle.exec: + default: op + minecity.cmd.city.clear.ride.exec: + default: op + minecity.cmd.city.deny.all.enter.exec: + default: op + minecity.cmd.city.deny.all.click.exec: + default: op + minecity.cmd.city.deny.all.pickup.exec: + default: op + minecity.cmd.city.deny.all.harvest.exec: + default: op + minecity.cmd.city.deny.all.open.exec: + default: op + minecity.cmd.city.deny.all.pvp.exec: + default: op + minecity.cmd.city.deny.all.pvc.exec: + default: op + minecity.cmd.city.deny.all.modify.exec: + default: op + minecity.cmd.city.deny.all.vehicle.exec: + default: op + minecity.cmd.city.deny.all.ride.exec: + default: op + minecity.cmd.city.allow.all.enter.exec: + default: op + minecity.cmd.city.allow.all.click.exec: + default: op + minecity.cmd.city.allow.all.pickup.exec: + default: op + minecity.cmd.city.allow.all.harvest.exec: + default: op + minecity.cmd.city.allow.all.open.exec: + default: op + minecity.cmd.city.allow.all.pvp.exec: + default: op + minecity.cmd.city.allow.all.pvc.exec: + default: op + minecity.cmd.city.allow.all.modify.exec: + default: op + minecity.cmd.city.allow.all.vehicle.exec: + default: op + minecity.cmd.city.allow.all.ride.exec: + default: op + minecity.cmd.city.clear.all.enter.exec: + default: op + minecity.cmd.city.clear.all.click.exec: + default: op + minecity.cmd.city.clear.all.pickup.exec: + default: op + minecity.cmd.city.clear.all.harvest.exec: + default: op + minecity.cmd.city.clear.all.open.exec: + default: op + minecity.cmd.city.clear.all.pvp.exec: + default: op + minecity.cmd.city.clear.all.pvc.exec: + default: op + minecity.cmd.city.clear.all.modify.exec: + default: op + minecity.cmd.city.clear.all.vehicle.exec: + default: op + minecity.cmd.city.clear.all.ride.exec: + default: op + minecity.cmd.plot.deny.enter.exec: + default: op + minecity.cmd.plot.deny.click.exec: + default: op + minecity.cmd.plot.deny.pickup.exec: + default: op + minecity.cmd.plot.deny.harvest.exec: + default: op + minecity.cmd.plot.deny.open.exec: + default: op + minecity.cmd.plot.deny.pvp.exec: + default: op + minecity.cmd.plot.deny.pvc.exec: + default: op + minecity.cmd.plot.deny.modify.exec: + default: op + minecity.cmd.plot.deny.vehicle.exec: + default: op + minecity.cmd.plot.deny.ride.exec: + default: op + minecity.cmd.plot.allow.enter.exec: + default: op + minecity.cmd.plot.allow.click.exec: + default: op + minecity.cmd.plot.allow.pickup.exec: + default: op + minecity.cmd.plot.allow.harvest.exec: + default: op + minecity.cmd.plot.allow.open.exec: + default: op + minecity.cmd.plot.allow.pvp.exec: + default: op + minecity.cmd.plot.allow.pvc.exec: + default: op + minecity.cmd.plot.allow.modify.exec: + default: op + minecity.cmd.plot.allow.vehicle.exec: + default: op + minecity.cmd.plot.allow.ride.exec: + default: op + minecity.cmd.plot.clear.enter.exec: + default: op + minecity.cmd.plot.clear.click.exec: + default: op + minecity.cmd.plot.clear.pickup.exec: + default: op + minecity.cmd.plot.clear.harvest.exec: + default: op + minecity.cmd.plot.clear.open.exec: + default: op + minecity.cmd.plot.clear.pvp.exec: + default: op + minecity.cmd.plot.clear.pvc.exec: + default: op + minecity.cmd.plot.clear.modify.exec: + default: op + minecity.cmd.plot.clear.vehicle.exec: + default: op + minecity.cmd.plot.clear.ride.exec: + default: op + minecity.cmd.plot.deny.all.enter.exec: + default: op + minecity.cmd.plot.deny.all.click.exec: + default: op + minecity.cmd.plot.deny.all.pickup.exec: + default: op + minecity.cmd.plot.deny.all.harvest.exec: + default: op + minecity.cmd.plot.deny.all.open.exec: + default: op + minecity.cmd.plot.deny.all.pvp.exec: + default: op + minecity.cmd.plot.deny.all.pvc.exec: + default: op + minecity.cmd.plot.deny.all.modify.exec: + default: op + minecity.cmd.plot.deny.all.vehicle.exec: + default: op + minecity.cmd.plot.deny.all.ride.exec: + default: op + minecity.cmd.plot.allow.all.enter.exec: + default: op + minecity.cmd.plot.allow.all.click.exec: + default: op + minecity.cmd.plot.allow.all.pickup.exec: + default: op + minecity.cmd.plot.allow.all.harvest.exec: + default: op + minecity.cmd.plot.allow.all.open.exec: + default: op + minecity.cmd.plot.allow.all.pvp.exec: + default: op + minecity.cmd.plot.allow.all.pvc.exec: + default: op + minecity.cmd.plot.allow.all.modify.exec: + default: op + minecity.cmd.plot.allow.all.vehicle.exec: + default: op + minecity.cmd.plot.allow.all.ride.exec: + default: op + minecity.cmd.plot.clear.all.enter.exec: + default: op + minecity.cmd.plot.clear.all.click.exec: + default: op + minecity.cmd.plot.clear.all.pickup.exec: + default: op + minecity.cmd.plot.clear.all.harvest.exec: + default: op + minecity.cmd.plot.clear.all.open.exec: + default: op + minecity.cmd.plot.clear.all.pvp.exec: + default: op + minecity.cmd.plot.clear.all.pvc.exec: + default: op + minecity.cmd.plot.clear.all.modify.exec: + default: op + minecity.cmd.plot.clear.all.vehicle.exec: + default: op + minecity.cmd.plot.clear.all.ride.exec: + default: op + minecity.cmd.plot.perms.enter.exec: + default: op + minecity.cmd.plot.perms.click.exec: + default: op + minecity.cmd.plot.perms.pickup.exec: + default: op + minecity.cmd.plot.perms.harvest.exec: + default: op + minecity.cmd.plot.perms.open.exec: + default: op + minecity.cmd.plot.perms.pvp.exec: + default: op + minecity.cmd.plot.perms.pvc.exec: + default: op + minecity.cmd.plot.perms.modify.exec: + default: op + minecity.cmd.plot.perms.vehicle.exec: + default: op + minecity.cmd.plot.perms.ride.exec: + default: op + minecity.cmd.plot.perms.exec: + default: op + minecity.cmd.city.perms.enter.exec: + default: op + minecity.cmd.city.perms.click.exec: + default: op + minecity.cmd.city.perms.pickup.exec: + default: op + minecity.cmd.city.perms.harvest.exec: + default: op + minecity.cmd.city.perms.open.exec: + default: op + minecity.cmd.city.perms.pvp.exec: + default: op + minecity.cmd.city.perms.pvc.exec: + default: op + minecity.cmd.city.perms.modify.exec: + default: op + minecity.cmd.city.perms.vehicle.exec: + default: op + minecity.cmd.city.perms.ride.exec: + default: op + minecity.cmd.city.perms.exec: + default: op + minecity.cmd.city.sell.exec: + default: op + minecity.cmd.city.buy.exec: + default: op + minecity.cmd.auto.claim.exec: + default: op + minecity.cmd.group.create.exec: + default: op + minecity.cmd.group.add.exec: + default: op + minecity.cmd.group.remove.exec: + default: op + minecity.cmd.group.list.exec: + default: op + minecity.cmd.group.info.exec: + default: op + minecity.cmd.group.delete.exec: + default: op + minecity.cmd.group.add.manager.exec: + default: op + minecity.cmd.group.remove.manager.exec: + default: op + minecity.cmd.confirm.exec: + default: op + minecity.cmd.help.exec: + default: op + minecity.cmd.reload.exec: + default: op + minecity.cmd.plot.create.exec: + default: op + minecity.cmd.plot.rename.exec: + default: op + minecity.cmd.plot.return.exec: + default: op + minecity.cmd.plot.transfer.exec: + default: op + minecity.cmd.plot.delete.exec: + default: op + minecity.cmd.plot.info.exec: + default: op + minecity.cmd.plot.readjust.exec: + default: op + minecity.cmd.city.list.exec: + default: op + minecity.cmd.plot.list.exec: + default: op + minecity.cmd.plot.sell.exec: + default: op + minecity.cmd.plot.buy.exec: + default: op diff --git a/Core/src/main/java/br/com/gamemods/minecity/MineCity.java b/Core/src/main/java/br/com/gamemods/minecity/MineCity.java index 2d63d246..751ba534 100644 --- a/Core/src/main/java/br/com/gamemods/minecity/MineCity.java +++ b/Core/src/main/java/br/com/gamemods/minecity/MineCity.java @@ -1,397 +1,397 @@ -package br.com.gamemods.minecity; - -import br.com.gamemods.minecity.api.DistinctQueue; -import br.com.gamemods.minecity.api.PlayerID; -import br.com.gamemods.minecity.api.Server; -import br.com.gamemods.minecity.api.Slow; -import br.com.gamemods.minecity.api.command.*; -import br.com.gamemods.minecity.api.permission.SimpleFlagHolder; -import br.com.gamemods.minecity.api.world.*; -import br.com.gamemods.minecity.commands.*; -import br.com.gamemods.minecity.datasource.api.DataSourceException; -import br.com.gamemods.minecity.datasource.api.IDataSource; -import br.com.gamemods.minecity.datasource.api.unchecked.DBConsumer; -import br.com.gamemods.minecity.datasource.api.unchecked.DBSupplier; -import br.com.gamemods.minecity.datasource.api.unchecked.DisDBConsumer; -import br.com.gamemods.minecity.datasource.api.unchecked.UncheckedDataSourceException; -import br.com.gamemods.minecity.datasource.sql.SQLSource; -import br.com.gamemods.minecity.economy.EconomyLayer; -import br.com.gamemods.minecity.economy.EconomyProxy; -import br.com.gamemods.minecity.permission.PermissionLayer; -import br.com.gamemods.minecity.permission.PermissionProxy; -import br.com.gamemods.minecity.structure.*; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Predicate; -import java.util.stream.Stream; - -public class MineCity -{ - public static final Random RANDOM = new Random(); - @NotNull - public final IDataSource dataSource; - public final Server server; - public final CommandTree commands = new CommandTree(); - private final ConcurrentHashMap natures = new ConcurrentHashMap<>(); - private final ConcurrentHashMap chunks = new ConcurrentHashMap<>(); - public final ConcurrentHashMap mapCache = new ConcurrentHashMap<>(); - public final Queue entityUpdates = new ConcurrentLinkedQueue<>(); - public ExecutorService mapService = Executors.newSingleThreadExecutor(r-> new Thread(r, "MineCityMapService")); - @SuppressWarnings("OptionalUsedAsFieldOrParameterType") - public Optional worldProvider = Optional.empty(); - public MessageTransformer messageTransformer; - public SimpleFlagHolder defaultNatureFlags = new SimpleFlagHolder(); - public SimpleFlagHolder defaultCityFlags = new SimpleFlagHolder(); - public SimpleFlagHolder defaultPlotFlags = new SimpleFlagHolder(); - public SimpleFlagHolder defaultReserveFlags = new SimpleFlagHolder(); - public MineCityConfig.Costs costs; - public MineCityConfig.Limits limits; - private Queue reloadQueue = new DistinctQueue<>(); - public boolean lazyReloads = true; - public Locale locale; - public boolean useTitles; - @NotNull - public EconomyProxy economy; - @NotNull - public PermissionProxy permission; - - @SuppressWarnings("LanguageMismatch") - public MineCity(@NotNull Server server, @NotNull MineCityConfig config, @Nullable IDataSource dataSource, - @NotNull MessageTransformer messageTransformer) - { - defaultCityFlags = config.defaultCityFlags; - defaultNatureFlags = config.defaultNatureFlags; - defaultPlotFlags = config.defaultPlotFlags; - defaultReserveFlags = config.defaultReserveFlags; - locale = config.locale; - useTitles = config.useTitle; - costs = config.costs; - limits = config.limits; - - this.server = server; - this.messageTransformer = messageTransformer; - this.dataSource = dataSource == null? new SQLSource(this, config) : dataSource; - if(config.dbPass != null) - Arrays.fill(config.dbPass, (byte) 0); - - commands.dataSource = this.dataSource; - commands.onlinePlayers = server::getOnlinePlayerNames; - commands.cityNames = this.dataSource.cityNameSupplier(); - commands.scheduler = server::runAsynchronously; - commands.messageTransformer = ()-> messageTransformer; - commands.optionTransformer = (id, args) -> - Arrays.stream(args).map(arg -> - { - String[] options = arg.options(); - if(options.length == 0) - return arg; - - for(int i = 0; i < options.length; i++) - { - String option = options[i]; - options[i] = messageTransformer.toSimpleText(new Message( - "cmd."+id+".arg."+arg.name().toLowerCase().replaceAll("[^a-z0-9]+", "-")+".option."+ - option.toLowerCase().replaceAll("[^a-z-0-9]+","-"), - option - )).replaceAll("\\s",""); - } - - return new TranslatedOptions(arg, options); - }).toArray(Arg[]::new) - ; - commands.registerCommands(new CityCommand(this)); - new PermissionCommands(this).register(commands); - commands.registerCommands(new GroupCommand(this)); - commands.registerCommands(GeneralCommands.class); - commands.registerCommands(PlotCommand.class); - Inconsistency.setMineCity(this); - - economy = EconomyLayer.load(this, config.economy); - permission = PermissionLayer.load(this, config.permission); - } - - public MineCity(Server server, MineCityConfig config) - { - this(server, config, null, new MessageTransformer()); - } - - public MineCity(Server server, MineCityConfig config, MessageTransformer messageTransformer) - { - this(server, config, null, messageTransformer); - } - - @NotNull - public Optional getCity(@NotNull ChunkPos pos) - { - return getChunk(pos).flatMap(ClaimedChunk::getCity); - } - - @NotNull - public Optional getPlot(@NotNull BlockPos pos) - { - return getChunk(pos.getChunk()).flatMap(c-> c.getPlotAt(pos)); - } - - @NotNull - public Optional getChunk(@NotNull BlockPos pos) - { - return getChunk(pos.getChunk()); - } - - @NotNull - public Optional getChunk(@NotNull ChunkPos pos) - { - return Optional.ofNullable(getChunkProvider().map(p-> p.getClaim(pos)).orElseGet(()-> chunks.get(pos))); - } - - @NotNull - public ClaimedChunk provideChunk(@NotNull ChunkPos pos, @Nullable ClaimedChunk cache) - { - if(cache != null && !cache.isInvalid() && pos.equals(cache.chunk)) - return cache; - - return provideChunk(pos); - } - - @NotNull - public ClaimedChunk provideChunk(@NotNull ChunkPos pos) - { - return getChunk(pos).orElseGet(()-> Inconsistency.claim(pos)); - } - - @NotNull - public ChunkPos provideChunk(@NotNull WorldDim world, int x, int z) - { - return getChunkProvider().map(p-> p.getChunk(world, x, z)).orElseGet(()-> new ChunkPos(world, x, z)); - } - - /** - * Gets a chunk claim data from the memory when it's available or fetches from the database when it's not - * @return Empty optional if the chunk is unloaded and not claimed. Non-empty optional may still contains an - * unclaimed chunk that is already loaded. - */ - @Slow - public Optional getOrFetchChunkUnchecked(@NotNull ChunkPos pos) - { - return Optional.ofNullable(getChunk(pos).orElseGet((DBSupplier) () -> dataSource.getCityChunk(pos))); - } - - public Optional getOrFetchChunk(@NotNull ChunkPos pos) throws DataSourceException - { - try - { - return getOrFetchChunkUnchecked(pos); - } - catch(UncheckedDataSourceException e) - { - throw e.getCause(); - } - } - - @Nullable - public Nature getNature(@NotNull WorldDim world) - { - if(world.nature != null && world.nature.isValid()) - return world.nature; - - return natures.get(world); - } - - @NotNull - public Nature loadNature(@NotNull WorldDim world) throws DataSourceException - { - Nature nature = natures.get(world); - if(nature != null) - unloadNature(world); - - nature = dataSource.getNature(world); - world.nature = nature; - natures.put(world, nature); - return nature; - } - - @NotNull - public Nature nature(@NotNull WorldDim world) - { - Nature nature = getNature(world); - if(nature != null && nature.isValid()) return nature; - try - { - return loadNature(world); - } - catch(DataSourceException e) - { - return Inconsistency.nature(world); - } - } - - public Optional getChunkProvider() - { - return worldProvider.flatMap(WorldProvider::getChunkProvider); - } - - @Slow - @NotNull - public ClaimedChunk loadChunk(@NotNull ChunkPos pos) throws DataSourceException - { - ClaimedChunk chunk = Optional.ofNullable(dataSource.getCityChunk(pos)) - .orElseGet(()-> new ClaimedChunk(nature(pos.world), pos)); - - if(!getChunkProvider().map(p-> p.setClaim(chunk)).orElse(false)) - { - ClaimedChunk removed = chunks.put(pos, chunk); - if(removed != null) - removed.invalidate(); - } - - mapCache.remove(pos); - - return chunk; - } - - public Stream loadedChunks() - { - Stream stream = chunks.values().stream(); - Optional> provider = getChunkProvider().map(ChunkProvider::loadedChunks); - if(provider.isPresent()) - return Stream.concat(stream, provider.get()); - return stream; - } - - @Slow - public void reloadChunkSlowly(ChunkPos pos) - { - if(!lazyReloads) - { - try - { - reloadChunk(pos); - } - catch(DataSourceException e) - { - e.printStackTrace(); - } - return; - } - - ClaimedChunk claim = Inconsistency.claim(pos); - if(!getChunkProvider().map(p-> p.setClaim(claim)).orElse(false)) - { - ClaimedChunk removed = chunks.put(pos, claim); - if(removed != null) - removed.invalidate(); - } - mapCache.remove(pos); - - reloadQueue.offer(pos); - } - - @Slow - public boolean reloadQueuedChunk() - { - ChunkPos pos = reloadQueue.poll(); - if(pos == null) - return false; - - try - { - reloadChunk(pos); - } - catch(DataSourceException e) - { - e.printStackTrace(); - } - return true; - } - - public void reloadChunksUnchecked(Predicate condition) - { - loadedChunks().filter(condition).map(ClaimedChunk::getChunk).forEach((DisDBConsumer) this::loadChunk); - } - - @Slow - public void reloadChunks(Predicate condition) throws DataSourceException - { - try - { - loadedChunks().filter(condition).map(ClaimedChunk::getChunk).forEach((DBConsumer) this::loadChunk); - } - catch(UncheckedDataSourceException e) - { - throw e.getCause(); - } - } - - @Slow - @Nullable - public ClaimedChunk reloadChunk(@NotNull ChunkPos pos) throws DataSourceException - { - if(!chunks.containsKey(pos) && !getChunkProvider().map(p-> p.getClaim(pos)).isPresent()) - return null; - - return loadChunk(pos); - } - - @Nullable - public ClaimedChunk unloadChunk(@NotNull ChunkPos pos) - { - ClaimedChunk chunk = chunks.remove(pos); - chunk = getChunkProvider().map(p-> p.getClaim(pos)).orElse(chunk); - - if(chunk != null) - chunk.invalidate(); - return chunk; - } - - @Nullable - public Nature unloadNature(@NotNull WorldDim world) - { - chunks.entrySet().removeIf(e-> { - if(e.getKey().world.equals(world)) - { - e.getValue().invalidate(); - return true; - } - return false; - }); - mapCache.keySet().removeIf(c -> c.world.equals(world)); - - Nature nature = natures.remove(world); - if(nature != null) - nature.invalidate(); - return nature; - } - - @Slow - public Optional getPlayer(String name) throws DataSourceException - { - Optional result = dataSource.getPlayer(name); - if(result.isPresent()) - return result; - - return server.getPlayerId(name); - } - - @Slow - public Optional findPlayer(String playerName) throws UncheckedDataSourceException - { - Optional playerId = server.getPlayerId(playerName); - if(playerId.isPresent()) - return playerId; - - try - { - return dataSource.getPlayer(playerName); - } - catch(DataSourceException e) - { - throw new UncheckedDataSourceException(e); - } - } -} +package br.com.gamemods.minecity; + +import br.com.gamemods.minecity.api.DistinctQueue; +import br.com.gamemods.minecity.api.PlayerID; +import br.com.gamemods.minecity.api.Server; +import br.com.gamemods.minecity.api.Slow; +import br.com.gamemods.minecity.api.command.*; +import br.com.gamemods.minecity.api.permission.SimpleFlagHolder; +import br.com.gamemods.minecity.api.world.*; +import br.com.gamemods.minecity.commands.*; +import br.com.gamemods.minecity.datasource.api.DataSourceException; +import br.com.gamemods.minecity.datasource.api.IDataSource; +import br.com.gamemods.minecity.datasource.api.unchecked.DBConsumer; +import br.com.gamemods.minecity.datasource.api.unchecked.DBSupplier; +import br.com.gamemods.minecity.datasource.api.unchecked.DisDBConsumer; +import br.com.gamemods.minecity.datasource.api.unchecked.UncheckedDataSourceException; +import br.com.gamemods.minecity.datasource.sql.SQLSource; +import br.com.gamemods.minecity.economy.EconomyLayer; +import br.com.gamemods.minecity.economy.EconomyProxy; +import br.com.gamemods.minecity.permission.PermissionLayer; +import br.com.gamemods.minecity.permission.PermissionProxy; +import br.com.gamemods.minecity.structure.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.function.Predicate; +import java.util.stream.Stream; + +public class MineCity +{ + public static final Random RANDOM = new Random(); + @NotNull + public final IDataSource dataSource; + public final Server server; + public final CommandTree commands = new CommandTree(); + private final ConcurrentHashMap natures = new ConcurrentHashMap<>(); + private final ConcurrentHashMap chunks = new ConcurrentHashMap<>(); + public final ConcurrentHashMap mapCache = new ConcurrentHashMap<>(); + public final Queue entityUpdates = new ConcurrentLinkedQueue<>(); + public ExecutorService mapService = Executors.newSingleThreadExecutor(r-> new Thread(r, "MineCityMapService")); + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + public Optional worldProvider = Optional.empty(); + public MessageTransformer messageTransformer; + public SimpleFlagHolder defaultNatureFlags = new SimpleFlagHolder(); + public SimpleFlagHolder defaultCityFlags = new SimpleFlagHolder(); + public SimpleFlagHolder defaultPlotFlags = new SimpleFlagHolder(); + public SimpleFlagHolder defaultReserveFlags = new SimpleFlagHolder(); + public MineCityConfig.Costs costs; + public MineCityConfig.Limits limits; + private Queue reloadQueue = new DistinctQueue<>(); + public boolean lazyReloads = true; + public Locale locale; + public boolean useTitles; + @NotNull + public EconomyProxy economy; + @NotNull + public PermissionProxy permission; + + @SuppressWarnings("LanguageMismatch") + public MineCity(@NotNull Server server, @NotNull MineCityConfig config, @Nullable IDataSource dataSource, + @NotNull MessageTransformer messageTransformer) + { + defaultCityFlags = config.defaultCityFlags; + defaultNatureFlags = config.defaultNatureFlags; + defaultPlotFlags = config.defaultPlotFlags; + defaultReserveFlags = config.defaultReserveFlags; + locale = config.locale; + useTitles = config.useTitle; + costs = config.costs; + limits = config.limits; + + this.server = server; + this.messageTransformer = messageTransformer; + this.dataSource = dataSource == null? new SQLSource(this, config) : dataSource; + if(config.dbPass != null) + Arrays.fill(config.dbPass, (byte) 0); + + commands.dataSource = this.dataSource; + commands.onlinePlayers = server::getOnlinePlayerNames; + commands.cityNames = this.dataSource.cityNameSupplier(); + commands.scheduler = server::runAsynchronously; + commands.messageTransformer = ()-> messageTransformer; + commands.optionTransformer = (id, args) -> + Arrays.stream(args).map(arg -> + { + String[] options = arg.options(); + if(options.length == 0) + return arg; + + for(int i = 0; i < options.length; i++) + { + String option = options[i]; + options[i] = messageTransformer.toSimpleText(new Message( + "cmd."+id+".arg."+arg.name().toLowerCase().replaceAll("[^a-z0-9]+", "-")+".option."+ + option.toLowerCase().replaceAll("[^a-z-0-9]+","-"), + option + )).replaceAll("\\s",""); + } + + return new TranslatedOptions(arg, options); + }).toArray(Arg[]::new) + ; + commands.registerCommands(new CityCommand(this)); + new PermissionCommands(this).register(commands); + commands.registerCommands(new GroupCommand(this)); + commands.registerCommands(GeneralCommands.class); + commands.registerCommands(PlotCommand.class); + Inconsistency.setMineCity(this); + + economy = EconomyLayer.load(this, config.economy); + permission = PermissionLayer.load(this, config.permission); + } + + public MineCity(Server server, MineCityConfig config) + { + this(server, config, null, new MessageTransformer()); + } + + public MineCity(Server server, MineCityConfig config, MessageTransformer messageTransformer) + { + this(server, config, null, messageTransformer); + } + + @NotNull + public Optional getCity(@NotNull ChunkPos pos) + { + return getChunk(pos).flatMap(ClaimedChunk::getCity); + } + + @NotNull + public Optional getPlot(@NotNull BlockPos pos) + { + return getChunk(pos.getChunk()).flatMap(c-> c.getPlotAt(pos)); + } + + @NotNull + public Optional getChunk(@NotNull BlockPos pos) + { + return getChunk(pos.getChunk()); + } + + @NotNull + public Optional getChunk(@NotNull ChunkPos pos) + { + return Optional.ofNullable(getChunkProvider().map(p-> p.getClaim(pos)).orElseGet(()-> chunks.get(pos))); + } + + @NotNull + public ClaimedChunk provideChunk(@NotNull ChunkPos pos, @Nullable ClaimedChunk cache) + { + if(cache != null && !cache.isInvalid() && pos.equals(cache.chunk)) + return cache; + + return provideChunk(pos); + } + + @NotNull + public ClaimedChunk provideChunk(@NotNull ChunkPos pos) + { + return getChunk(pos).orElseGet(()-> Inconsistency.claim(pos)); + } + + @NotNull + public ChunkPos provideChunk(@NotNull WorldDim world, int x, int z) + { + return getChunkProvider().map(p-> p.getChunk(world, x, z)).orElseGet(()-> new ChunkPos(world, x, z)); + } + + /** + * Gets a chunk claim data from the memory when it's available or fetches from the database when it's not + * @return Empty optional if the chunk is unloaded and not claimed. Non-empty optional may still contains an + * unclaimed chunk that is already loaded. + */ + @Slow + public Optional getOrFetchChunkUnchecked(@NotNull ChunkPos pos) + { + return Optional.ofNullable(getChunk(pos).orElseGet((DBSupplier) () -> dataSource.getCityChunk(pos))); + } + + public Optional getOrFetchChunk(@NotNull ChunkPos pos) throws DataSourceException + { + try + { + return getOrFetchChunkUnchecked(pos); + } + catch(UncheckedDataSourceException e) + { + throw e.getCause(); + } + } + + @Nullable + public Nature getNature(@NotNull WorldDim world) + { + if(world.nature != null && world.nature.isValid()) + return world.nature; + + return natures.get(world); + } + + @NotNull + public Nature loadNature(@NotNull WorldDim world) throws DataSourceException + { + Nature nature = natures.get(world); + if(nature != null) + unloadNature(world); + + nature = dataSource.getNature(world); + world.nature = nature; + natures.put(world, nature); + return nature; + } + + @NotNull + public Nature nature(@NotNull WorldDim world) + { + Nature nature = getNature(world); + if(nature != null && nature.isValid()) return nature; + try + { + return loadNature(world); + } + catch(DataSourceException e) + { + return Inconsistency.nature(world); + } + } + + public Optional getChunkProvider() + { + return worldProvider.flatMap(WorldProvider::getChunkProvider); + } + + @Slow + @NotNull + public ClaimedChunk loadChunk(@NotNull ChunkPos pos) throws DataSourceException + { + ClaimedChunk chunk = Optional.ofNullable(dataSource.getCityChunk(pos)) + .orElseGet(()-> new ClaimedChunk(nature(pos.world), pos)); + + if(!getChunkProvider().map(p-> p.setClaim(chunk)).orElse(false)) + { + ClaimedChunk removed = chunks.put(pos, chunk); + if(removed != null) + removed.invalidate(); + } + + mapCache.remove(pos); + + return chunk; + } + + public Stream loadedChunks() + { + Stream stream = chunks.values().stream(); + Optional> provider = getChunkProvider().map(ChunkProvider::loadedChunks); + if(provider.isPresent()) + return Stream.concat(stream, provider.get()); + return stream; + } + + @Slow + public void reloadChunkSlowly(ChunkPos pos) + { + if(!lazyReloads) + { + try + { + reloadChunk(pos); + } + catch(DataSourceException e) + { + e.printStackTrace(); + } + return; + } + + ClaimedChunk claim = Inconsistency.claim(pos); + if(!getChunkProvider().map(p-> p.setClaim(claim)).orElse(false)) + { + ClaimedChunk removed = chunks.put(pos, claim); + if(removed != null) + removed.invalidate(); + } + mapCache.remove(pos); + + reloadQueue.offer(pos); + } + + @Slow + public boolean reloadQueuedChunk() + { + ChunkPos pos = reloadQueue.poll(); + if(pos == null) + return false; + + try + { + reloadChunk(pos); + } + catch(DataSourceException e) + { + e.printStackTrace(); + } + return true; + } + + public void reloadChunksUnchecked(Predicate condition) + { + loadedChunks().filter(condition).map(ClaimedChunk::getChunk).forEach((DisDBConsumer) this::loadChunk); + } + + @Slow + public void reloadChunks(Predicate condition) throws DataSourceException + { + try + { + loadedChunks().filter(condition).map(ClaimedChunk::getChunk).forEach((DBConsumer) this::loadChunk); + } + catch(UncheckedDataSourceException e) + { + throw e.getCause(); + } + } + + @Slow + @Nullable + public ClaimedChunk reloadChunk(@NotNull ChunkPos pos) throws DataSourceException + { + if(!chunks.containsKey(pos) && !getChunkProvider().map(p-> p.getClaim(pos)).isPresent()) + return null; + + return loadChunk(pos); + } + + @Nullable + public ClaimedChunk unloadChunk(@NotNull ChunkPos pos) + { + ClaimedChunk chunk = chunks.remove(pos); + chunk = getChunkProvider().map(p-> p.getClaim(pos)).orElse(chunk); + + if(chunk != null) + chunk.invalidate(); + return chunk; + } + + @Nullable + public Nature unloadNature(@NotNull WorldDim world) + { + chunks.entrySet().removeIf(e-> { + if(e.getKey().world.equals(world)) + { + e.getValue().invalidate(); + return true; + } + return false; + }); + mapCache.keySet().removeIf(c -> c.world.equals(world)); + + Nature nature = natures.remove(world); + if(nature != null) + nature.invalidate(); + return nature; + } + + @Slow + public Optional getPlayer(String name) throws DataSourceException + { + Optional result = dataSource.getPlayer(name); + if(result.isPresent()) + return result; + + return server.getPlayerId(name); + } + + @Slow + public Optional findPlayer(String playerName) throws UncheckedDataSourceException + { + Optional playerId = server.getPlayerId(playerName); + if(playerId.isPresent()) + return playerId; + + try + { + return dataSource.getPlayer(playerName); + } + catch(DataSourceException e) + { + throw new UncheckedDataSourceException(e); + } + } +} diff --git a/Core/src/main/java/br/com/gamemods/minecity/MineCityConfig.java b/Core/src/main/java/br/com/gamemods/minecity/MineCityConfig.java index af81eb14..7d62ca2d 100644 --- a/Core/src/main/java/br/com/gamemods/minecity/MineCityConfig.java +++ b/Core/src/main/java/br/com/gamemods/minecity/MineCityConfig.java @@ -1,60 +1,60 @@ -package br.com.gamemods.minecity; - -import br.com.gamemods.minecity.api.permission.SimpleFlagHolder; -import br.com.gamemods.minecity.economy.Tax; - -import java.util.Locale; - -public final class MineCityConfig implements Cloneable -{ - public String dbUrl = "jdbc:mysql://localhost/minecity?autoReconnect=true"; - public String dbUser; - public byte[] dbPass; - public Locale locale; - public SimpleFlagHolder defaultNatureFlags = new SimpleFlagHolder(); - public SimpleFlagHolder defaultCityFlags = new SimpleFlagHolder(); - public SimpleFlagHolder defaultPlotFlags = new SimpleFlagHolder(); - public SimpleFlagHolder defaultReserveFlags = new SimpleFlagHolder(); - public boolean defaultNatureDisableCities; - public boolean useTitle = true; - public String economy = "none"; - public String permission = "none"; - public Costs costs = new Costs(); - public Limits limits = new Limits(); - - @Override - public MineCityConfig clone() - { - try - { - MineCityConfig clone = (MineCityConfig) super.clone(); - clone.dbPass = dbPass.clone(); - return clone; - } - catch(CloneNotSupportedException e) - { - throw new UnsupportedOperationException(e); - } - } - - public static class Costs - { - public double cityCreation = 1000; - public double islandCreation = 500; - public double claim = 25; - public Tax cityTax = new Tax(100, 0.03); - public Tax cityTaxApplied = new Tax(-1, 0.05); - public Tax plotTaxApplied = new Tax(0, 0); - public double cityChangeSpawn = 50; - public double plotChangeSpawn = 50; - public double goToCity = 5; - public double goToPlot = 15; - } - - public static class Limits - { - public int cities = -1; - public int claims = -1; - public int islands = -1; - } -} +package br.com.gamemods.minecity; + +import br.com.gamemods.minecity.api.permission.SimpleFlagHolder; +import br.com.gamemods.minecity.economy.Tax; + +import java.util.Locale; + +public final class MineCityConfig implements Cloneable +{ + public String dbUrl = "jdbc:mysql://localhost/minecity?autoReconnect=true"; + public String dbUser; + public byte[] dbPass; + public Locale locale; + public SimpleFlagHolder defaultNatureFlags = new SimpleFlagHolder(); + public SimpleFlagHolder defaultCityFlags = new SimpleFlagHolder(); + public SimpleFlagHolder defaultPlotFlags = new SimpleFlagHolder(); + public SimpleFlagHolder defaultReserveFlags = new SimpleFlagHolder(); + public boolean defaultNatureDisableCities; + public boolean useTitle = true; + public String economy = "none"; + public String permission = "none"; + public Costs costs = new Costs(); + public Limits limits = new Limits(); + + @Override + public MineCityConfig clone() + { + try + { + MineCityConfig clone = (MineCityConfig) super.clone(); + clone.dbPass = dbPass.clone(); + return clone; + } + catch(CloneNotSupportedException e) + { + throw new UnsupportedOperationException(e); + } + } + + public static class Costs + { + public double cityCreation = 1000; + public double islandCreation = 500; + public double claim = 25; + public Tax cityTax = new Tax(100, 0.03); + public Tax cityTaxApplied = new Tax(-1, 0.05); + public Tax plotTaxApplied = new Tax(0, 0); + public double cityChangeSpawn = 50; + public double plotChangeSpawn = 50; + public double goToCity = 5; + public double goToPlot = 15; + } + + public static class Limits + { + public int cities = -1; + public int claims = -1; + public int islands = -1; + } +} diff --git a/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLCityStorage.java b/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLCityStorage.java index 36b6161e..887556b3 100644 --- a/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLCityStorage.java +++ b/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLCityStorage.java @@ -1,1479 +1,1479 @@ -package br.com.gamemods.minecity.datasource.sql; - -import br.com.gamemods.minecity.api.PlayerID; -import br.com.gamemods.minecity.api.Slow; -import br.com.gamemods.minecity.api.command.Message; -import br.com.gamemods.minecity.api.permission.EntityID; -import br.com.gamemods.minecity.api.permission.Group; -import br.com.gamemods.minecity.api.permission.Identity; -import br.com.gamemods.minecity.api.permission.OptionalPlayer; -import br.com.gamemods.minecity.api.shape.Shape; -import br.com.gamemods.minecity.api.world.BlockPos; -import br.com.gamemods.minecity.api.world.ChunkPos; -import br.com.gamemods.minecity.api.world.MinecraftEntity; -import br.com.gamemods.minecity.api.world.WorldDim; -import br.com.gamemods.minecity.datasource.api.DataSourceException; -import br.com.gamemods.minecity.datasource.api.ICityStorage; -import br.com.gamemods.minecity.datasource.api.unchecked.DBConsumer; -import br.com.gamemods.minecity.economy.Tax; -import br.com.gamemods.minecity.structure.City; -import br.com.gamemods.minecity.structure.Island; -import br.com.gamemods.minecity.structure.IslandArea; -import br.com.gamemods.minecity.structure.Plot; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.sql.*; -import java.util.*; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Collectors; - -public class SQLCityStorage implements ICityStorage -{ - @NotNull - private final SQLSource source; - - @NotNull - private final SQLConnection connection; - - @NotNull - private final SQLPermStorage permStorage; - - SQLCityStorage(@NotNull SQLSource source, @NotNull SQLConnection connection, @NotNull SQLPermStorage permStorage) - { - this.source = source; - this.connection = connection; - this.permStorage = permStorage; - } - - @Override - public void deleteCity(@NotNull City city) throws DataSourceException - { - int cityId = city.getId(); - if(cityId <= 0) - throw new IllegalStateException("cityId = "+cityId); - - try(Connection transaction = connection.transaction()) - { - try(PreparedStatement pst = transaction.prepareStatement( - "DELETE FROM minecity_city WHERE city_id=?" - )) - { - pst.setInt(1, cityId); - source.executeUpdate(pst, 1); - transaction.commit(); - source.cityNames.remove(city.getName()); - source.groupNames.remove(city.getIdentityName()); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @Override - public void setOwner(@NotNull City city, @NotNull OptionalPlayer owner) throws DataSourceException, IllegalStateException - { - if(city.owner().equals(owner)) - return; - - int cityId = city.getId(); - if(cityId <= 0) throw new IllegalStateException("The city is not registered"); - - try - { - Connection connection = this.connection.connect(); - int ownerId = source.playerId(connection, owner); - - try(PreparedStatement pst = connection.prepareStatement( - "UPDATE `minecity_city` SET `owner`=? WHERE `city_id`=?" - )) - { - source.setNullableInt(pst, 1, ownerId); - pst.setInt(2, cityId); - if(pst.executeUpdate() <= 0) - throw new DataSourceException("Tried to change the owner of "+ cityId+" from "+city.owner()+" to "+owner+" but nothing changed"); - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @NotNull - @Override - public Collection reserve(@NotNull IslandArea reserve) throws DataSourceException - { - SQLIsland sqlIsland = (SQLIsland) reserve.island; - StringBuilder sbx = new StringBuilder(), sbz = new StringBuilder(); - Runnable build = ()-> - { - sbx.setLength(0); sbz.setLength(0); - reserve.claims().forEach(c->{ sbx.append(c.x).append(','); sbz.append(c.z).append(','); }); - if(sbx.length() > 0) - sbx.setLength(sbx.length() - 1); - if(sbz.length() > 0) - sbz.setLength(sbz.length() - 1); - }; - build.run(); - - try(Connection transaction = connection.transaction(); Statement stm = transaction.createStatement()) - { - try - { - int worldId = source.worldId(transaction, sqlIsland.world); - Collection chunks = new HashSet<>(); - String x = sbx.toString(), z = sbz.toString(); - - if(!x.isEmpty()) - { - - ResultSet results = stm.executeQuery("SELECT x, z FROM minecity_chunks WHERE world_id="+worldId+" AND island_id!="+sqlIsland.id+" AND x IN("+x+") AND z IN("+z+");"); - while(results.next()) - reserve.setClaimed(results.getInt(1), results.getInt(2), false); - results.close(); - - results = stm.executeQuery("SELECT x,z FROM minecity_chunks WHERE island_id="+sqlIsland.id+" LIMIT 1"); - results.next(); - ChunkPos pos = new ChunkPos(sqlIsland.world, results.getInt(1), results.getInt(2)); - results.close(); - - Set valid = reserve.contiguous(pos); - reserve.claims().filter(c-> !valid.contains(c)).forEach(c-> reserve.setClaimed(c, false)); - build.run(); - x = sbx.toString(); z = sbz.toString(); - } - - - String deleteCond = "island_id="+sqlIsland.id+" AND reserve=1"; - if(!x.isEmpty()) - deleteCond+= " AND x NOT IN ("+x+") AND z NOT IN ("+z+")"; - - ResultSet results = stm.executeQuery("SELECT x,z FROM minecity_chunks WHERE " + deleteCond+";"); - while(results.next()) - chunks.add(new ChunkPos(sqlIsland.world, results.getInt(1), results.getInt(2))); - results.close(); - - stm.executeUpdate("DELETE FROM minecity_chunks WHERE "+deleteCond+";"); - - if(!x.isEmpty()) - { - results = stm.executeQuery("SELECT x, z FROM minecity_chunks WHERE world_id="+worldId+" AND x IN("+x+") AND z IN("+z+");"); - while(results.next()) - reserve.setClaimed(results.getInt(1), results.getInt(2), false); - results.close(); - - sbx.setLength(0); - List insert = reserve.claims().collect(Collectors.toList()); - chunks.addAll(insert); - insert.forEach(c-> - sbx.append('(').append(worldId).append(',').append(c.x).append(',').append(c.z).append(',') - .append(sqlIsland.id).append(",1),") - ); - if(sbx.length() > 0) - { - sbx.setLength(sbx.length()-1); - stm.executeUpdate("INSERT INTO minecity_chunks(world_id,x,z,island_id,reserve) VALUES "+sbx+";"); - } - } - transaction.commit(); - return chunks; - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - private void disclaim(Connection transaction, ChunkPos chunk, int islandId, boolean enforce) throws DataSourceException, SQLException - { - try(PreparedStatement pst = transaction.prepareStatement( - "DELETE FROM `minecity_chunks` WHERE `world_id`=? AND `x`=? AND `z`=? AND `island_id`=?" - )) - { - pst.setInt(1, source.worldId(transaction, chunk.world)); - pst.setInt(2, chunk.x); - pst.setInt(3, chunk.z); - pst.setInt(4, islandId); - if(enforce) - source.executeUpdate(pst, 1); - else - pst.executeUpdate(); - } - } - - @Slow - @Override - public void deleteIsland(@NotNull Island island) throws DataSourceException, IllegalArgumentException - { - SQLIsland sqlIsland = (SQLIsland) island; - if(sqlIsland.chunkCount == 0) throw new IllegalArgumentException(); - - try(Connection transaction = this.connection.transaction()) - { - try(PreparedStatement pst = transaction.prepareStatement( - "DELETE FROM `minecity_islands` WHERE `island_id`=?" - )) - { - pst.setInt(1, sqlIsland.id); - int i = pst.executeUpdate(); - if(i != 1) - throw new DataSourceException("Expecting 1 change, "+i+" changed"); - - transaction.commit(); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - - sqlIsland.chunkCount = sqlIsland.maxX = sqlIsland.minX = sqlIsland.maxZ = sqlIsland.minZ = 0; - source.mineCity.reloadChunksUnchecked(c-> c.getIsland().filter(island::equals).isPresent()); - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - private void updateCount(Connection transaction, SQLIsland sqlIsland) throws SQLException - { - try(PreparedStatement pst = transaction.prepareStatement( - "SELECT MIN(x), MAX(x), MIN(z), MAX(z), COUNT(*) FROM minecity_chunks WHERE island_id=? AND reserve=0" - )) - { - pst.setInt(1, sqlIsland.id); - ResultSet result = pst.executeQuery(); - result.next(); - sqlIsland.minX = result.getInt(1); - sqlIsland.maxX = result.getInt(2); - sqlIsland.minZ = result.getInt(3); - sqlIsland.maxZ = result.getInt(4); - sqlIsland.chunkCount = result.getInt(5); - } - } - - @Slow - @Override - public void disclaim(@NotNull ChunkPos chunk, @NotNull Island island) - throws DataSourceException, IllegalArgumentException - { - SQLIsland sqlIsland = (SQLIsland) island; - if(sqlIsland.chunkCount == 0) throw new IllegalArgumentException(); - - try(Connection transaction = connection.transaction()) - { - try - { - disclaim(transaction, chunk, sqlIsland.id, true); - transaction.commit(); - - updateCount(transaction, sqlIsland); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - - try - { - source.mineCity.reloadChunk(chunk); - } - catch(Exception e) - { - e.printStackTrace(); - } - } - - @Slow - @NotNull - @Override - @SuppressWarnings("OptionalGetWithoutIsPresent") - public Collection disclaim(@NotNull ChunkPos chunk, @NotNull Island island, @NotNull Set> groups) - throws DataSourceException, IllegalStateException, NoSuchElementException, ClassCastException, IllegalArgumentException - { - SQLIsland sqlIsland = (SQLIsland) island; - if(sqlIsland.chunkCount == 0) throw new IllegalArgumentException(); - int cityId = sqlIsland.city.getId(); - - Set mainGroup = groups.stream().max((a,b)-> a.size()-b.size() ).get(); - groups = groups.stream().filter(s-> s != mainGroup).collect(Collectors.toSet()); - - try(Connection transaction = connection.transaction(); Statement stm = transaction.createStatement()) - { - try - { - disclaim(transaction, chunk, sqlIsland.id, true); - int worldId = source.worldId(transaction, sqlIsland.world); - - - stm.executeUpdate("DELETE FROM minecity_chunks WHERE island_id="+sqlIsland.id+" AND reserve=1;"); - - List islands = new ArrayList<>(groups.size()); - int[] expected = new int[groups.size()]; int i = 0; - for(Set group : groups) - { - int islandId = source.createIsland(transaction, cityId, sqlIsland.world); - StringBuilder sb = new StringBuilder(); - int minX = Integer.MAX_VALUE, minZ = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE, maxZ = Integer.MIN_VALUE; - for(ChunkPos pos : group) - { - minX = Math.min(minX, pos.x); - minZ = Math.min(minZ, pos.z); - maxX = Math.max(maxX, pos.x); - maxZ = Math.max(maxZ, pos.z); - sb.append("(x=").append(pos.x).append(" AND z=").append(pos.z).append(") OR"); - } - - sb.setLength(sb.length() - 3); - - stm.addBatch("UPDATE minecity_chunks SET island_id="+islandId+" " + - "WHERE world_id="+worldId+" AND island_id="+sqlIsland.id+" AND reserve=0 AND ("+sb+");" - ); - - SQLIsland newIsland = new SQLIsland(sqlIsland.city, this, permStorage, islandId, minX, maxX, minZ, maxZ, group.size(), sqlIsland.world, Collections.emptySet()); - expected[i++] = newIsland.chunkCount; - islands.add(newIsland); - } - - int[] result = stm.executeBatch(); - if(!Arrays.equals(expected, result)) - { - throw new DataSourceException("Unexpected result after reclaiming to new islands. " + - "Expected: "+Arrays.toString(expected)+" Result: "+Arrays.toString(result)); - } - - Collection plots = sqlIsland.getPlots(); - List afterCommit = new ArrayList<>(plots.size()); - if(!plots.isEmpty()) - { - try(PreparedStatement select = transaction.prepareStatement( - "SELECT island_id FROM minecity_chunks WHERE world_id=? AND x=? AND z=? AND reserve=0" - ); PreparedStatement update = transaction.prepareStatement( - "UPDATE minecity_plots SET island_id=? WHERE plot_id=?" - )) - { - for(Plot plot: plots) - { - ChunkPos spawn = plot.getSpawn().getChunk(); - select.setInt(1, worldId); - select.setInt(2, spawn.x); - select.setInt(3, spawn.z); - ResultSet selectRes = select.executeQuery(); - if(!selectRes.next()) - throw new DataSourceException("The plot id:"+plot.id+" name:"+plot.getIdentityName()+" is not in an island!"); - int newIslandId = selectRes.getInt(1); - selectRes.close(); - - if(plot.getIsland().id == newIslandId) - continue; - - SQLIsland newIsland = null; - for(Island possible : islands) - { - if(possible.id == newIslandId) - { - newIsland = (SQLIsland) possible; - break; - } - } - - if(newIsland == null) - throw new DataSourceException("The plot id:"+plot.id+" name:"+plot.getIdentityName()+ - " would be moved to the island:"+newIslandId+" but that island wasn't created by " + - "this disclaim!"); - - update.setInt(1, newIslandId); - update.setInt(2, plot.id); - source.executeUpdate(update, 1); - - SQLIsland finalNewIsland = newIsland; - afterCommit.add(()-> sqlIsland.relocate(plot, finalNewIsland)); - } - } - } - - updateCount(transaction, sqlIsland); - transaction.commit(); - afterCommit.forEach(Runnable::run); - - return islands; - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Override - public double invested(@NotNull City city, double value) throws DataSourceException - { - try(Connection transaction = connection.transaction()) - { - try - { - try(PreparedStatement pst = transaction.prepareStatement( - "UPDATE minecity_city SET `investment`=`investment`+? WHERE city_id=?" - )) - { - pst.setDouble(1, value); - pst.setInt(2, city.getId()); - source.executeUpdate(pst, 1); - } - - double investment; - try(PreparedStatement pst = transaction.prepareStatement( - "SELECT `investment` FROM `minecity_city` WHERE `city_id`=?" - )) - { - pst.setInt(1, city.getId()); - ResultSet result = pst.executeQuery(); - result.next(); - investment = result.getDouble(1); - } - - transaction.commit(); - return investment; - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Override - public double invested(@NotNull Plot plot, double value) throws DataSourceException - { - try(Connection transaction = connection.transaction()) - { - try - { - try(PreparedStatement pst = transaction.prepareStatement( - "UPDATE minecity_plots SET `investment`=`investment`+? WHERE plot_id=?" - )) - { - pst.setDouble(1, value); - pst.setInt(2, plot.id); - source.executeUpdate(pst, 1); - } - - double investment; - try(PreparedStatement pst = transaction.prepareStatement( - "SELECT `investment` FROM `minecity_plots` WHERE `plot_id`=?" - )) - { - pst.setInt(1, plot.id); - ResultSet result = pst.executeQuery(); - result.next(); - investment = result.getDouble(1); - } - - transaction.commit(); - return investment; - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Override - public void setInvestment(@NotNull Plot plot, double investment) throws DataSourceException - { - try(Connection transaction = connection.transaction()) - { - try - { - try(PreparedStatement pst = transaction.prepareStatement( - "UPDATE minecity_plots SET `investment`=? WHERE plot_id=?" - )) - { - pst.setDouble(1, investment); - pst.setInt(2, plot.id); - source.executeUpdate(pst, 1); - } - - transaction.commit(); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Override - public void setPrice(@NotNull Plot plot, double price) throws DataSourceException - { - try(Connection transaction = connection.transaction()) - { - try - { - try(PreparedStatement pst = transaction.prepareStatement( - "UPDATE minecity_plots SET `price`=? WHERE plot_id=?" - )) - { - pst.setDouble(1, price); - pst.setInt(2, plot.id); - source.executeUpdate(pst, 1); - } - - transaction.commit(); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Override - public void setPrice(@NotNull City city, double price) throws DataSourceException - { - try(Connection transaction = connection.transaction()) - { - try - { - try(PreparedStatement pst = transaction.prepareStatement( - "UPDATE minecity_city SET `price`=? WHERE city_id=?" - )) - { - pst.setDouble(1, price); - pst.setInt(2, city.getId()); - source.executeUpdate(pst, 1); - } - - transaction.commit(); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @Override - public void setName(@NotNull City city, @NotNull String identity, @NotNull String name) throws DataSourceException - { - try(Connection transaction = connection.transaction()) - { - String previous = city.getName(); - try - { - if(identity.equals(city.getIdentityName())) - try(PreparedStatement pst = transaction.prepareStatement( - "UPDATE minecity_city SET `display_name`=? WHERE city_id=?" - )) - { - pst.setString(1, name); - pst.setInt(2, city.getId()); - source.executeUpdate(pst, 1); - } - else - try(PreparedStatement pst = transaction.prepareStatement( - "UPDATE minecity_city SET `name`=?, display_name=? WHERE city_id=?" - )) - { - pst.setString(1, identity); - pst.setString(2, name); - pst.setInt(3, city.getId()); - source.executeUpdate(pst, 1); - } - - transaction.commit(); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - source.cityNames.remove(previous); - source.cityNames.add(name); - Set groups = source.groupNames.remove(identity); - if(groups != null) - source.groupNames.put(city.getIdentityName(), groups); - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @NotNull - @Override - public Group createGroup(@NotNull City city, @NotNull String id, @NotNull String name) throws DataSourceException - { - try(Connection transaction = connection.transaction()) - { - try(PreparedStatement pst = transaction.prepareStatement( - "INSERT INTO minecity_groups(city_id,name,display_name) VALUES(?,?,?)" - , PreparedStatement.RETURN_GENERATED_KEYS - )) - { - pst.setInt(1, city.getId()); - pst.setString(2, id); - pst.setString(3, name); - pst.executeUpdate(); - ResultSet generatedKeys = pst.getGeneratedKeys(); - generatedKeys.next(); - int groupId = generatedKeys.getInt(1); - - transaction.commit(); - source.groupNames.computeIfAbsent(city.getIdentityName(), i-> new HashSet<>(1)).add(name); - return new Group(this, groupId, city, id, name, Collections.emptySet(), Collections.emptySet()); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @Override - public void setName(@NotNull Group group, @NotNull String identity, @NotNull String name) throws DataSourceException - { - try(Connection transaction = connection.connect()) - { - try(PreparedStatement pst = transaction.prepareStatement( - "UPDATE minecity_groups SET `name`=?, display_name=? WHERE group_id=?" - )) - { - pst.setString(1, identity); - pst.setString(2, name); - pst.setInt(3, group.id); - int count = pst.executeUpdate(); - if(count != 1) - throw new DataSourceException("Expected 1 change but got "+count+" changes"); - - Set groups = source.groupNames.computeIfAbsent(group.home.getIdentityName(), i-> new HashSet<>(1)); - groups.remove(group.getName()); - groups.add(name); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @Override - public void deleteGroup(@NotNull Group group) throws DataSourceException - { - try(Connection transaction = connection.transaction()) - { - try(PreparedStatement pst = transaction.prepareStatement( - "DELETE FROM minecity_groups WHERE group_id=?" - )) - { - pst.setInt(1, group.id); - source.executeUpdate(pst, 1); - transaction.commit(); - source.groupNames.computeIfAbsent(group.home.getIdentityName(), i-> new HashSet<>(0)).remove(group.getName()); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @Override - public void addMember(@NotNull Group group, @NotNull Identity member) - throws DataSourceException, UnsupportedOperationException - { - try(Connection transaction = this.connection.transaction(); Statement stm = transaction.createStatement()) - { - try - { - switch(member.getType()) - { - case PLAYER: - { - int playerId = source.playerId(transaction, (PlayerID) member); - stm.executeUpdate("INSERT INTO minecity_group_players(group_id,player_id) VALUES("+group.id+","+playerId+");"); - break; - } - case ENTITY: - { - int entityId = source.entityId(transaction, (EntityID) member); - stm.executeUpdate("INSERT INTO minecity_group_entities(group_id,entity_id) VALUES("+group.id+","+entityId+");"); - break; - } - default: - throw new UnsupportedOperationException("Unsupported identity type: "+member.getType()); - } - - transaction.commit(); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - catch(ClassCastException e) - { - throw new UnsupportedOperationException(e); - } - } - - @Slow - @Override - public void addManager(@NotNull Group group, @NotNull PlayerID manager) - throws DataSourceException, UnsupportedOperationException - { - try(Connection transaction = this.connection.transaction(); Statement stm = transaction.createStatement()) - { - try - { - int playerId = source.playerId(transaction, manager); - stm.executeUpdate("INSERT INTO minecity_group_managers(group_id,player_id) VALUES("+group.id+","+playerId+");"); - - transaction.commit(); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - catch(ClassCastException e) - { - throw new UnsupportedOperationException(e); - } - } - - @Slow - @Override - public void removeMember(@NotNull Group group, @NotNull Identity member) - throws DataSourceException, UnsupportedOperationException - { - try(Connection transaction = this.connection.transaction(); Statement stm = transaction.createStatement()) - { - try - { - switch(member.getType()) - { - case PLAYER: - { - int playerId = source.playerId(transaction, (PlayerID) member); - int changes = stm.executeUpdate("DELETE FROM minecity_group_players WHERE group_id="+group.id+" AND player_id="+playerId+";"); - if(changes != 1) - throw new DataSourceException("Expected 1 change, got "+changes+" changes"); - break; - } - case ENTITY: - { - int entityId = source.entityId(transaction, (EntityID) member); - int changes = stm.executeUpdate("INSERT INTO minecity_group_entities WHERE group_id="+group.id+" AND entity_id="+entityId+";"); - if(changes != 1) - throw new DataSourceException("Expected 1 change, got "+changes+" changes"); - break; - } - default: - throw new UnsupportedOperationException("Unsupported identity type: "+member.getType()); - } - - transaction.commit(); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - catch(ClassCastException e) - { - throw new UnsupportedOperationException(e); - } - } - - @Slow - @Override - public void removeManager(@NotNull Group group, @NotNull PlayerID manager) - throws DataSourceException, UnsupportedOperationException - { - try(Connection transaction = this.connection.transaction(); Statement stm = transaction.createStatement()) - { - try - { - int playerId = source.playerId(transaction, manager); - int changes = stm.executeUpdate("DELETE FROM minecity_group_managers WHERE group_id="+group.id+" AND player_id="+playerId+";"); - if(changes != 1) - throw new DataSourceException("Expected 1 change, got "+changes+" changes"); - - transaction.commit(); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - catch(ClassCastException e) - { - throw new UnsupportedOperationException(e); - } - } - - @Slow - @NotNull - @Override - public Collection loadIslands(City city) throws DataSourceException - { - try - { - Connection connection = this.connection.connect(); - int cityId = city.getId(); - try(PreparedStatement pst = connection.prepareStatement( - "SELECT c.island_id, MIN(x), MAX(x), MIN(z), MAX(z), COUNT(*), i.world_id, w.dim, w.world, w.`name` " + - "FROM minecity_chunks c " + - "INNER JOIN minecity_islands AS i ON c.island_id=i.island_id " + - "INNER JOIN minecity_world AS w ON i.world_id=w.world_id " + - "WHERE i.city_id = ? AND c.reserve=0 " + - "GROUP BY c.island_id" - )) - { - pst.setInt(1, cityId); - ArrayList islands = new ArrayList<>(3); - ResultSet result = pst.executeQuery(); - while(result.next()) - { - WorldDim world = source.world(result.getInt(7), ()->result.getInt(8), ()->result.getString(9), ()->result.getString(10)); - islands.add(new SQLIsland(this, permStorage, - result.getInt(1), result.getInt(2), result.getInt(3), - result.getInt(4), result.getInt(5), result.getInt(6), world, city - )); - } - islands.trimToSize(); - return islands; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @NotNull - @Override - public Collection loadGroups(@NotNull City city) throws DataSourceException - { - try - { - Connection connection = this.connection.connect(); - try(PreparedStatement groupPst = connection.prepareStatement( - "SELECT group_id, name, display_name FROM minecity_groups WHERE city_id=?" - ); - PreparedStatement playerPst = connection.prepareStatement( - "SELECT p.player_id, player_uuid, player_name " + - "FROM minecity_group_players gp " + - "INNER JOIN minecity_players p ON p.player_id = gp.player_id " + - "WHERE gp.group_id = ?" - ); - PreparedStatement entityPst = connection.prepareStatement( - "SELECT e.entity_id, entity_uuid, entity_name, entity_type " + - "FROM minecity_group_entities ge " + - "INNER JOIN minecity_entities e ON e.entity_id = ge.entity_id " + - "WHERE ge.group_id = ?" - ); - PreparedStatement managersPst = connection.prepareStatement( - "SELECT p.player_id, player_uuid, player_name " + - "FROM minecity_group_managers gm " + - "INNER JOIN minecity_players p ON p.player_id = gm.player_id " + - "WHERE gm.group_id = ?" - ) - ) - { - groupPst.setInt(1, city.getId()); - ResultSet groupResult = groupPst.executeQuery(); - List groups = new ArrayList<>(); - while(groupResult.next()) - { - int groupId = groupResult.getInt(1); - playerPst.setInt(1, groupId); - entityPst.setInt(1, groupId); - managersPst.setInt(1, groupId); - - List managers = new ArrayList<>(); - List> members = new ArrayList<>(); - - try(ResultSet managerResult = managersPst.executeQuery()) - { - while(managerResult.next()) - members.add(new PlayerID(managerResult.getInt("player_id"), - source.uuid(managerResult.getBytes("player_uuid")), - managerResult.getString("player_name") - )); - } - - try(ResultSet memberResult = playerPst.executeQuery()) - { - while(memberResult.next()) - members.add(new PlayerID(memberResult.getInt("player_id"), - source.uuid(memberResult.getBytes("player_uuid")), - memberResult.getString("player_name") - )); - } - - try(ResultSet memberResult = entityPst.executeQuery()) - { - while(memberResult.next()) - members.add(new EntityID(memberResult.getInt("entity_id"), - MinecraftEntity.Type.valueOf(memberResult.getString("entity_type")), - source.uuid(memberResult.getBytes("entity_uuid")), - memberResult.getString("entity_name") - )); - } - - groups.add(new Group(this, groupId, city, groupResult.getString(2), groupResult.getString(3), members, managers)); - } - - return groups; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @NotNull - @Override - public Island createIsland(@NotNull City city, @NotNull ChunkPos chunk) - throws DataSourceException, IllegalStateException - { - int cityId = city.getId(); - if(cityId <= 0) throw new IllegalStateException("The city is not registered"); - - try(Connection transaction = connection.transaction()) - { - try - { - SQLIsland island = new SQLIsland(this, permStorage, source.createIsland(transaction, cityId, chunk.world), chunk, city); - source.createClaim(transaction, island.id, chunk); - island.city = city; - - transaction.commit(); - - return island; - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @Override - public void claim(@NotNull Island island, @NotNull ChunkPos chunk) throws DataSourceException - { - SQLIsland sqlIsland = (SQLIsland) island; - try(Connection transaction = connection.transaction()) - { - try - { - source.createClaim(connection.connect(), sqlIsland.id, chunk); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - sqlIsland.add(chunk); - - source.mineCity.reloadChunk(chunk); - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @NotNull - @Override - @SuppressWarnings("OptionalGetWithoutIsPresent") - public Island claim(@NotNull Set islands, @NotNull ChunkPos chunk) - throws DataSourceException, IllegalStateException, NoSuchElementException - { - if(islands.size() == 1) - { - Island island = islands.iterator().next(); - claim(island, chunk); - return island; - } - - List sqlIslands = islands.stream().map(island -> (SQLIsland) island).collect(Collectors.toList()); - SQLIsland mainIsland = sqlIslands.stream().max((a, b) -> a.getChunkCount() - b.getChunkCount()).get(); - List merge = sqlIslands.stream().filter(island -> island != mainIsland).collect(Collectors.toList()); - try(Connection transaction = connection.transaction(); Statement stm = transaction.createStatement()) - { - try - { - StringBuilder sb = new StringBuilder(); - merge.forEach(island -> sb.append(island.id).append(", ")); - sb.setLength(sb.length()-2); - String array = sb.toString(); - - List chunksToUpdate = new ArrayList<>(); - try(ResultSet result = stm.executeQuery("SELECT c.world_id, c.x, c.z, w.dim, w.world, w.name " + - "FROM minecity_chunks c INNER JOIN minecity_world w ON c.world_id = w.world_id " + - "WHERE c.island_id IN("+array+");") - ){ - while(result.next()) - { - WorldDim world = source.world(result.getInt(1),()->result.getInt(4),()->result.getString(5),()->result.getString(6)); - chunksToUpdate.add(new ChunkPos(world, result.getInt(2), result.getInt(3))); - } - } - - stm.executeUpdate("UPDATE `minecity_chunks` SET `island_id`="+mainIsland.id+" WHERE `island_id` IN("+array+");"); - stm.executeUpdate("DELETE FROM `minecity_islands` WHERE `island_id` IN("+array+");"); - source.createClaim(transaction, mainIsland.id, chunk); - - transaction.commit(); - - mainIsland.add(chunk); - - merge.forEach(island -> { - mainIsland.minX = Math.min(mainIsland.minX, island.minX); - mainIsland.maxX = Math.max(mainIsland.maxX, island.maxX); - mainIsland.minZ = Math.min(mainIsland.minZ, island.minZ); - mainIsland.maxZ = Math.max(mainIsland.maxZ, island.maxZ); - mainIsland.chunkCount += island.chunkCount; - - island.minX = island.maxX = island.minZ = island.maxZ = island.chunkCount = 0; - }); - - chunksToUpdate.forEach((DBConsumer) source.mineCity::reloadChunk); - return mainIsland; - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @Override - public void setSpawn(@NotNull City city, @NotNull BlockPos spawn) throws DataSourceException, IllegalStateException - { - if(city.getSpawn().equals(spawn)) - return; - - int cityId = city.getId(); - if(cityId <= 0) throw new IllegalStateException("The city is not registered"); - - try - { - Connection connection = this.connection.connect(); - int worldId = source.worldId(connection, spawn.world); - - try(PreparedStatement pst = connection.prepareStatement( - "UPDATE `minecity_city` SET `spawn_world`=?, `spawn_x`=?, `spawn_y`=?, `spawn_z`=? WHERE `city_id`=?" - )) - { - pst.setInt(1, worldId); - pst.setInt(2, spawn.x); - //noinspection SuspiciousNameCombination - pst.setInt(3, spawn.y); - pst.setInt(4, spawn.z); - pst.setInt(5, cityId); - if(pst.executeUpdate() <= 0) - throw new DataSourceException("Tried to change spawn of "+ cityId+" from "+city.getSpawn()+" to "+spawn+" but nothing changed"); - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @Override - @SuppressWarnings("SuspiciousNameCombination") - public int createPlot(Plot plot) throws DataSourceException - { - try(Connection transaction = connection.transaction()) - { - try - { - int plotId; - try(PreparedStatement pst = transaction.prepareStatement( - "INSERT INTO minecity_plots(island_id,name,display_name,owner,spawn_x,spawn_y,spawn_z,shape,tax_accepted_flat,tax_accepted_percent,tax_applied_flat,tax_applied_percent,investment) " + - "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)", - Statement.RETURN_GENERATED_KEYS - )) - { - pst.setInt(1, plot.getIsland().getId()); - pst.setString(2, plot.getIdentityName()); - pst.setString(3, plot.getName()); - source.setNullableInt(pst, 4, source.playerId(transaction, plot.getOwner().orElse(null))); - BlockPos spawn = plot.getSpawn(); - pst.setInt(5, spawn.x); - pst.setInt(6, spawn.y); - pst.setInt(7, spawn.z); - pst.setBytes(8, plot.getShape().serializeBytes()); - pst.setDouble(9, plot.getAcceptedTax().getFlat()); - pst.setDouble(10, plot.getAcceptedTax().getPercent()); - pst.setDouble(11, plot.getAppliedTax().getFlat()); - pst.setDouble(12, plot.getAppliedTax().getPercent()); - pst.setDouble(13, plot.getInvestment()); - pst.executeUpdate(); - - ResultSet result = pst.getGeneratedKeys(); - result.next(); - plotId = result.getInt(1); - } - - transaction.commit(); - return plotId; - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @Override - public void setOwner(@NotNull Plot plot, @Nullable PlayerID owner) throws DataSourceException, IllegalStateException - { - try(Connection transaction = connection.transaction()) - { - try - { - try(PreparedStatement pst = transaction.prepareStatement( - "UPDATE minecity_plots SET owner=? WHERE plot_id=?" - )) - { - source.setNullableInt(pst, 1, source.playerId(transaction, owner)); - pst.setInt(2, plot.id); - source.executeUpdate(pst, 1); - } - - transaction.commit(); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @Override - public void setShape(@NotNull Plot plot, @NotNull Shape shape, BlockPos spawn, @NotNull Island newIsland) throws DataSourceException - { - try(Connection transaction = connection.transaction()) - { - try - { - try(PreparedStatement pst = transaction.prepareStatement( - "UPDATE minecity_plots SET shape=?, island_id=? WHERE plot_id=?" - )) - { - pst.setBytes(1, shape.serializeBytes()); - pst.setInt(2, newIsland.id); - pst.setInt(3, plot.id); - source.executeUpdate(pst, 1); - } - - setSpawn(transaction, plot, spawn); - - transaction.commit(); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @Override - public void setName(@NotNull Plot plot, @NotNull String identity, @NotNull String name) throws DataSourceException - { - try(Connection transaction = connection.transaction()) - { - try - { - try(PreparedStatement pst = transaction.prepareStatement( - "UPDATE minecity_plots SET `name`=?, `display_name`=? WHERE plot_id=?" - )) - { - pst.setString(1, identity); - pst.setString(2, name); - pst.setInt(3, plot.id); - source.executeUpdate(pst, 1); - } - - transaction.commit(); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @SuppressWarnings("SuspiciousNameCombination") - private void setSpawn(@NotNull Connection transaction, @NotNull Plot plot, @NotNull BlockPos spawn) - throws DataSourceException, SQLException - { - try(PreparedStatement pst = transaction.prepareStatement( - "UPDATE minecity_plots SET spawn_x=?, spawn_y=?, spawn_z=? WHERE plot_id=?" - )) - { - pst.setInt(1, spawn.x); - pst.setInt(2, spawn.y); - pst.setInt(3, spawn.z); - pst.setInt(4, plot.id); - source.executeUpdate(pst, 1); - } - } - - @Slow - @Override - public void setSpawn(@NotNull Plot plot, @NotNull BlockPos spawn) throws DataSourceException - { - if(!spawn.world.equals(plot.getIsland().world)) - throw new IllegalArgumentException("Different world!"); - - try(Connection transaction = connection.transaction()) - { - try - { - setSpawn(transaction, plot, spawn); - transaction.commit(); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @Override - public void deletePlot(@NotNull Plot plot) throws DataSourceException - { - try(Connection transaction = connection.transaction()) - { - try(PreparedStatement pst = transaction.prepareStatement( - "DELETE FROM minecity_plots WHERE plot_id=?" - )) - { - pst.setInt(1, plot.id); - source.executeUpdate(pst, 1); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - - transaction.commit(); - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @NotNull - @Override - public Set loadPlots(@NotNull Island island) throws DataSourceException - { - try - { - try(PreparedStatement pst = connection.connect().prepareStatement( - "SELECT plot_id,`name`,display_name,spawn_x,spawn_y,spawn_z,shape, player_id,player_uuid,player_name,perm_denial_message, " + - "tax_accepted_flat, tax_accepted_percent, tax_applied_flat, tax_applied_percent, investment, price " + - "FROM minecity_plots LEFT JOIN minecity_players ON player_id=owner " + - "WHERE island_id=?" - )) - { - pst.setInt(1, island.id); - ResultSet result = pst.executeQuery(); - if(!result.next()) - return Collections.emptySet(); - - // Memory optimization, caching common Tax instances - HashMap taxCache = new HashMap<>(6); - Tax t = island.getCity().getAppliedTax(); - taxCache.put(t, t); - t = island.getCity().mineCity.costs.plotTaxApplied; - taxCache.put(t, t); - BiFunction tax = (flat, percent)-> taxCache.computeIfAbsent(new Tax(flat, percent), Function.identity()); - - HashSet plots = new HashSet<>(3); - do - { - PlayerID owner; - int ownerId = result.getInt(8); - if(ownerId > 0) - owner = PlayerID.get(source.uuid(result.getBytes(9)), result.getString(10)); - else - owner = null; - - Message denial; - String str = result.getString(11); - if(str == null) - denial = null; - else - denial = new Message("", "${msg}", new Object[]{"msg",str}); - - plots.add(new Plot(source.mineCity, this, permStorage, result.getInt(1), island, result.getString(2), result.getString(3), owner, - new BlockPos(island.world, result.getInt(4), result.getInt(5), result.getInt(6)), - Shape.deserializeBytes(result.getBytes(7)), denial, - tax.apply(result.getDouble("tax_accepted_flat"), result.getDouble("tax_accepted_percent")), - tax.apply(result.getDouble("tax_applied_flat"), result.getDouble("tax_applied_percent")), - result.getDouble("investment"), result.getDouble("price") - )); - } while(result.next()); - - return plots; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } -} +package br.com.gamemods.minecity.datasource.sql; + +import br.com.gamemods.minecity.api.PlayerID; +import br.com.gamemods.minecity.api.Slow; +import br.com.gamemods.minecity.api.command.Message; +import br.com.gamemods.minecity.api.permission.EntityID; +import br.com.gamemods.minecity.api.permission.Group; +import br.com.gamemods.minecity.api.permission.Identity; +import br.com.gamemods.minecity.api.permission.OptionalPlayer; +import br.com.gamemods.minecity.api.shape.Shape; +import br.com.gamemods.minecity.api.world.BlockPos; +import br.com.gamemods.minecity.api.world.ChunkPos; +import br.com.gamemods.minecity.api.world.MinecraftEntity; +import br.com.gamemods.minecity.api.world.WorldDim; +import br.com.gamemods.minecity.datasource.api.DataSourceException; +import br.com.gamemods.minecity.datasource.api.ICityStorage; +import br.com.gamemods.minecity.datasource.api.unchecked.DBConsumer; +import br.com.gamemods.minecity.economy.Tax; +import br.com.gamemods.minecity.structure.City; +import br.com.gamemods.minecity.structure.Island; +import br.com.gamemods.minecity.structure.IslandArea; +import br.com.gamemods.minecity.structure.Plot; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.sql.*; +import java.util.*; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class SQLCityStorage implements ICityStorage +{ + @NotNull + private final SQLSource source; + + @NotNull + private final SQLConnection connection; + + @NotNull + private final SQLPermStorage permStorage; + + SQLCityStorage(@NotNull SQLSource source, @NotNull SQLConnection connection, @NotNull SQLPermStorage permStorage) + { + this.source = source; + this.connection = connection; + this.permStorage = permStorage; + } + + @Override + public void deleteCity(@NotNull City city) throws DataSourceException + { + int cityId = city.getId(); + if(cityId <= 0) + throw new IllegalStateException("cityId = "+cityId); + + try(Connection transaction = connection.transaction()) + { + try(PreparedStatement pst = transaction.prepareStatement( + "DELETE FROM minecity_city WHERE city_id=?" + )) + { + pst.setInt(1, cityId); + source.executeUpdate(pst, 1); + transaction.commit(); + source.cityNames.remove(city.getName()); + source.groupNames.remove(city.getIdentityName()); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @Override + public void setOwner(@NotNull City city, @NotNull OptionalPlayer owner) throws DataSourceException, IllegalStateException + { + if(city.owner().equals(owner)) + return; + + int cityId = city.getId(); + if(cityId <= 0) throw new IllegalStateException("The city is not registered"); + + try + { + Connection connection = this.connection.connect(); + int ownerId = source.playerId(connection, owner); + + try(PreparedStatement pst = connection.prepareStatement( + "UPDATE `minecity_city` SET `owner`=? WHERE `city_id`=?" + )) + { + source.setNullableInt(pst, 1, ownerId); + pst.setInt(2, cityId); + if(pst.executeUpdate() <= 0) + throw new DataSourceException("Tried to change the owner of "+ cityId+" from "+city.owner()+" to "+owner+" but nothing changed"); + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @NotNull + @Override + public Collection reserve(@NotNull IslandArea reserve) throws DataSourceException + { + SQLIsland sqlIsland = (SQLIsland) reserve.island; + StringBuilder sbx = new StringBuilder(), sbz = new StringBuilder(); + Runnable build = ()-> + { + sbx.setLength(0); sbz.setLength(0); + reserve.claims().forEach(c->{ sbx.append(c.x).append(','); sbz.append(c.z).append(','); }); + if(sbx.length() > 0) + sbx.setLength(sbx.length() - 1); + if(sbz.length() > 0) + sbz.setLength(sbz.length() - 1); + }; + build.run(); + + try(Connection transaction = connection.transaction(); Statement stm = transaction.createStatement()) + { + try + { + int worldId = source.worldId(transaction, sqlIsland.world); + Collection chunks = new HashSet<>(); + String x = sbx.toString(), z = sbz.toString(); + + if(!x.isEmpty()) + { + + ResultSet results = stm.executeQuery("SELECT x, z FROM minecity_chunks WHERE world_id="+worldId+" AND island_id!="+sqlIsland.id+" AND x IN("+x+") AND z IN("+z+");"); + while(results.next()) + reserve.setClaimed(results.getInt(1), results.getInt(2), false); + results.close(); + + results = stm.executeQuery("SELECT x,z FROM minecity_chunks WHERE island_id="+sqlIsland.id+" LIMIT 1"); + results.next(); + ChunkPos pos = new ChunkPos(sqlIsland.world, results.getInt(1), results.getInt(2)); + results.close(); + + Set valid = reserve.contiguous(pos); + reserve.claims().filter(c-> !valid.contains(c)).forEach(c-> reserve.setClaimed(c, false)); + build.run(); + x = sbx.toString(); z = sbz.toString(); + } + + + String deleteCond = "island_id="+sqlIsland.id+" AND reserve=1"; + if(!x.isEmpty()) + deleteCond+= " AND x NOT IN ("+x+") AND z NOT IN ("+z+")"; + + ResultSet results = stm.executeQuery("SELECT x,z FROM minecity_chunks WHERE " + deleteCond+";"); + while(results.next()) + chunks.add(new ChunkPos(sqlIsland.world, results.getInt(1), results.getInt(2))); + results.close(); + + stm.executeUpdate("DELETE FROM minecity_chunks WHERE "+deleteCond+";"); + + if(!x.isEmpty()) + { + results = stm.executeQuery("SELECT x, z FROM minecity_chunks WHERE world_id="+worldId+" AND x IN("+x+") AND z IN("+z+");"); + while(results.next()) + reserve.setClaimed(results.getInt(1), results.getInt(2), false); + results.close(); + + sbx.setLength(0); + List insert = reserve.claims().collect(Collectors.toList()); + chunks.addAll(insert); + insert.forEach(c-> + sbx.append('(').append(worldId).append(',').append(c.x).append(',').append(c.z).append(',') + .append(sqlIsland.id).append(",1),") + ); + if(sbx.length() > 0) + { + sbx.setLength(sbx.length()-1); + stm.executeUpdate("INSERT INTO minecity_chunks(world_id,x,z,island_id,reserve) VALUES "+sbx+";"); + } + } + transaction.commit(); + return chunks; + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + private void disclaim(Connection transaction, ChunkPos chunk, int islandId, boolean enforce) throws DataSourceException, SQLException + { + try(PreparedStatement pst = transaction.prepareStatement( + "DELETE FROM `minecity_chunks` WHERE `world_id`=? AND `x`=? AND `z`=? AND `island_id`=?" + )) + { + pst.setInt(1, source.worldId(transaction, chunk.world)); + pst.setInt(2, chunk.x); + pst.setInt(3, chunk.z); + pst.setInt(4, islandId); + if(enforce) + source.executeUpdate(pst, 1); + else + pst.executeUpdate(); + } + } + + @Slow + @Override + public void deleteIsland(@NotNull Island island) throws DataSourceException, IllegalArgumentException + { + SQLIsland sqlIsland = (SQLIsland) island; + if(sqlIsland.chunkCount == 0) throw new IllegalArgumentException(); + + try(Connection transaction = this.connection.transaction()) + { + try(PreparedStatement pst = transaction.prepareStatement( + "DELETE FROM `minecity_islands` WHERE `island_id`=?" + )) + { + pst.setInt(1, sqlIsland.id); + int i = pst.executeUpdate(); + if(i != 1) + throw new DataSourceException("Expecting 1 change, "+i+" changed"); + + transaction.commit(); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + + sqlIsland.chunkCount = sqlIsland.maxX = sqlIsland.minX = sqlIsland.maxZ = sqlIsland.minZ = 0; + source.mineCity.reloadChunksUnchecked(c-> c.getIsland().filter(island::equals).isPresent()); + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + private void updateCount(Connection transaction, SQLIsland sqlIsland) throws SQLException + { + try(PreparedStatement pst = transaction.prepareStatement( + "SELECT MIN(x), MAX(x), MIN(z), MAX(z), COUNT(*) FROM minecity_chunks WHERE island_id=? AND reserve=0" + )) + { + pst.setInt(1, sqlIsland.id); + ResultSet result = pst.executeQuery(); + result.next(); + sqlIsland.minX = result.getInt(1); + sqlIsland.maxX = result.getInt(2); + sqlIsland.minZ = result.getInt(3); + sqlIsland.maxZ = result.getInt(4); + sqlIsland.chunkCount = result.getInt(5); + } + } + + @Slow + @Override + public void disclaim(@NotNull ChunkPos chunk, @NotNull Island island) + throws DataSourceException, IllegalArgumentException + { + SQLIsland sqlIsland = (SQLIsland) island; + if(sqlIsland.chunkCount == 0) throw new IllegalArgumentException(); + + try(Connection transaction = connection.transaction()) + { + try + { + disclaim(transaction, chunk, sqlIsland.id, true); + transaction.commit(); + + updateCount(transaction, sqlIsland); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + + try + { + source.mineCity.reloadChunk(chunk); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + + @Slow + @NotNull + @Override + @SuppressWarnings("OptionalGetWithoutIsPresent") + public Collection disclaim(@NotNull ChunkPos chunk, @NotNull Island island, @NotNull Set> groups) + throws DataSourceException, IllegalStateException, NoSuchElementException, ClassCastException, IllegalArgumentException + { + SQLIsland sqlIsland = (SQLIsland) island; + if(sqlIsland.chunkCount == 0) throw new IllegalArgumentException(); + int cityId = sqlIsland.city.getId(); + + Set mainGroup = groups.stream().max((a,b)-> a.size()-b.size() ).get(); + groups = groups.stream().filter(s-> s != mainGroup).collect(Collectors.toSet()); + + try(Connection transaction = connection.transaction(); Statement stm = transaction.createStatement()) + { + try + { + disclaim(transaction, chunk, sqlIsland.id, true); + int worldId = source.worldId(transaction, sqlIsland.world); + + + stm.executeUpdate("DELETE FROM minecity_chunks WHERE island_id="+sqlIsland.id+" AND reserve=1;"); + + List islands = new ArrayList<>(groups.size()); + int[] expected = new int[groups.size()]; int i = 0; + for(Set group : groups) + { + int islandId = source.createIsland(transaction, cityId, sqlIsland.world); + StringBuilder sb = new StringBuilder(); + int minX = Integer.MAX_VALUE, minZ = Integer.MAX_VALUE, maxX = Integer.MIN_VALUE, maxZ = Integer.MIN_VALUE; + for(ChunkPos pos : group) + { + minX = Math.min(minX, pos.x); + minZ = Math.min(minZ, pos.z); + maxX = Math.max(maxX, pos.x); + maxZ = Math.max(maxZ, pos.z); + sb.append("(x=").append(pos.x).append(" AND z=").append(pos.z).append(") OR"); + } + + sb.setLength(sb.length() - 3); + + stm.addBatch("UPDATE minecity_chunks SET island_id="+islandId+" " + + "WHERE world_id="+worldId+" AND island_id="+sqlIsland.id+" AND reserve=0 AND ("+sb+");" + ); + + SQLIsland newIsland = new SQLIsland(sqlIsland.city, this, permStorage, islandId, minX, maxX, minZ, maxZ, group.size(), sqlIsland.world, Collections.emptySet()); + expected[i++] = newIsland.chunkCount; + islands.add(newIsland); + } + + int[] result = stm.executeBatch(); + if(!Arrays.equals(expected, result)) + { + throw new DataSourceException("Unexpected result after reclaiming to new islands. " + + "Expected: "+Arrays.toString(expected)+" Result: "+Arrays.toString(result)); + } + + Collection plots = sqlIsland.getPlots(); + List afterCommit = new ArrayList<>(plots.size()); + if(!plots.isEmpty()) + { + try(PreparedStatement select = transaction.prepareStatement( + "SELECT island_id FROM minecity_chunks WHERE world_id=? AND x=? AND z=? AND reserve=0" + ); PreparedStatement update = transaction.prepareStatement( + "UPDATE minecity_plots SET island_id=? WHERE plot_id=?" + )) + { + for(Plot plot: plots) + { + ChunkPos spawn = plot.getSpawn().getChunk(); + select.setInt(1, worldId); + select.setInt(2, spawn.x); + select.setInt(3, spawn.z); + ResultSet selectRes = select.executeQuery(); + if(!selectRes.next()) + throw new DataSourceException("The plot id:"+plot.id+" name:"+plot.getIdentityName()+" is not in an island!"); + int newIslandId = selectRes.getInt(1); + selectRes.close(); + + if(plot.getIsland().id == newIslandId) + continue; + + SQLIsland newIsland = null; + for(Island possible : islands) + { + if(possible.id == newIslandId) + { + newIsland = (SQLIsland) possible; + break; + } + } + + if(newIsland == null) + throw new DataSourceException("The plot id:"+plot.id+" name:"+plot.getIdentityName()+ + " would be moved to the island:"+newIslandId+" but that island wasn't created by " + + "this disclaim!"); + + update.setInt(1, newIslandId); + update.setInt(2, plot.id); + source.executeUpdate(update, 1); + + SQLIsland finalNewIsland = newIsland; + afterCommit.add(()-> sqlIsland.relocate(plot, finalNewIsland)); + } + } + } + + updateCount(transaction, sqlIsland); + transaction.commit(); + afterCommit.forEach(Runnable::run); + + return islands; + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Override + public double invested(@NotNull City city, double value) throws DataSourceException + { + try(Connection transaction = connection.transaction()) + { + try + { + try(PreparedStatement pst = transaction.prepareStatement( + "UPDATE minecity_city SET `investment`=`investment`+? WHERE city_id=?" + )) + { + pst.setDouble(1, value); + pst.setInt(2, city.getId()); + source.executeUpdate(pst, 1); + } + + double investment; + try(PreparedStatement pst = transaction.prepareStatement( + "SELECT `investment` FROM `minecity_city` WHERE `city_id`=?" + )) + { + pst.setInt(1, city.getId()); + ResultSet result = pst.executeQuery(); + result.next(); + investment = result.getDouble(1); + } + + transaction.commit(); + return investment; + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Override + public double invested(@NotNull Plot plot, double value) throws DataSourceException + { + try(Connection transaction = connection.transaction()) + { + try + { + try(PreparedStatement pst = transaction.prepareStatement( + "UPDATE minecity_plots SET `investment`=`investment`+? WHERE plot_id=?" + )) + { + pst.setDouble(1, value); + pst.setInt(2, plot.id); + source.executeUpdate(pst, 1); + } + + double investment; + try(PreparedStatement pst = transaction.prepareStatement( + "SELECT `investment` FROM `minecity_plots` WHERE `plot_id`=?" + )) + { + pst.setInt(1, plot.id); + ResultSet result = pst.executeQuery(); + result.next(); + investment = result.getDouble(1); + } + + transaction.commit(); + return investment; + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Override + public void setInvestment(@NotNull Plot plot, double investment) throws DataSourceException + { + try(Connection transaction = connection.transaction()) + { + try + { + try(PreparedStatement pst = transaction.prepareStatement( + "UPDATE minecity_plots SET `investment`=? WHERE plot_id=?" + )) + { + pst.setDouble(1, investment); + pst.setInt(2, plot.id); + source.executeUpdate(pst, 1); + } + + transaction.commit(); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Override + public void setPrice(@NotNull Plot plot, double price) throws DataSourceException + { + try(Connection transaction = connection.transaction()) + { + try + { + try(PreparedStatement pst = transaction.prepareStatement( + "UPDATE minecity_plots SET `price`=? WHERE plot_id=?" + )) + { + pst.setDouble(1, price); + pst.setInt(2, plot.id); + source.executeUpdate(pst, 1); + } + + transaction.commit(); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Override + public void setPrice(@NotNull City city, double price) throws DataSourceException + { + try(Connection transaction = connection.transaction()) + { + try + { + try(PreparedStatement pst = transaction.prepareStatement( + "UPDATE minecity_city SET `price`=? WHERE city_id=?" + )) + { + pst.setDouble(1, price); + pst.setInt(2, city.getId()); + source.executeUpdate(pst, 1); + } + + transaction.commit(); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @Override + public void setName(@NotNull City city, @NotNull String identity, @NotNull String name) throws DataSourceException + { + try(Connection transaction = connection.transaction()) + { + String previous = city.getName(); + try + { + if(identity.equals(city.getIdentityName())) + try(PreparedStatement pst = transaction.prepareStatement( + "UPDATE minecity_city SET `display_name`=? WHERE city_id=?" + )) + { + pst.setString(1, name); + pst.setInt(2, city.getId()); + source.executeUpdate(pst, 1); + } + else + try(PreparedStatement pst = transaction.prepareStatement( + "UPDATE minecity_city SET `name`=?, display_name=? WHERE city_id=?" + )) + { + pst.setString(1, identity); + pst.setString(2, name); + pst.setInt(3, city.getId()); + source.executeUpdate(pst, 1); + } + + transaction.commit(); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + source.cityNames.remove(previous); + source.cityNames.add(name); + Set groups = source.groupNames.remove(identity); + if(groups != null) + source.groupNames.put(city.getIdentityName(), groups); + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @NotNull + @Override + public Group createGroup(@NotNull City city, @NotNull String id, @NotNull String name) throws DataSourceException + { + try(Connection transaction = connection.transaction()) + { + try(PreparedStatement pst = transaction.prepareStatement( + "INSERT INTO minecity_groups(city_id,name,display_name) VALUES(?,?,?)" + , PreparedStatement.RETURN_GENERATED_KEYS + )) + { + pst.setInt(1, city.getId()); + pst.setString(2, id); + pst.setString(3, name); + pst.executeUpdate(); + ResultSet generatedKeys = pst.getGeneratedKeys(); + generatedKeys.next(); + int groupId = generatedKeys.getInt(1); + + transaction.commit(); + source.groupNames.computeIfAbsent(city.getIdentityName(), i-> new HashSet<>(1)).add(name); + return new Group(this, groupId, city, id, name, Collections.emptySet(), Collections.emptySet()); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @Override + public void setName(@NotNull Group group, @NotNull String identity, @NotNull String name) throws DataSourceException + { + try(Connection transaction = connection.connect()) + { + try(PreparedStatement pst = transaction.prepareStatement( + "UPDATE minecity_groups SET `name`=?, display_name=? WHERE group_id=?" + )) + { + pst.setString(1, identity); + pst.setString(2, name); + pst.setInt(3, group.id); + int count = pst.executeUpdate(); + if(count != 1) + throw new DataSourceException("Expected 1 change but got "+count+" changes"); + + Set groups = source.groupNames.computeIfAbsent(group.home.getIdentityName(), i-> new HashSet<>(1)); + groups.remove(group.getName()); + groups.add(name); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @Override + public void deleteGroup(@NotNull Group group) throws DataSourceException + { + try(Connection transaction = connection.transaction()) + { + try(PreparedStatement pst = transaction.prepareStatement( + "DELETE FROM minecity_groups WHERE group_id=?" + )) + { + pst.setInt(1, group.id); + source.executeUpdate(pst, 1); + transaction.commit(); + source.groupNames.computeIfAbsent(group.home.getIdentityName(), i-> new HashSet<>(0)).remove(group.getName()); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @Override + public void addMember(@NotNull Group group, @NotNull Identity member) + throws DataSourceException, UnsupportedOperationException + { + try(Connection transaction = this.connection.transaction(); Statement stm = transaction.createStatement()) + { + try + { + switch(member.getType()) + { + case PLAYER: + { + int playerId = source.playerId(transaction, (PlayerID) member); + stm.executeUpdate("INSERT INTO minecity_group_players(group_id,player_id) VALUES("+group.id+","+playerId+");"); + break; + } + case ENTITY: + { + int entityId = source.entityId(transaction, (EntityID) member); + stm.executeUpdate("INSERT INTO minecity_group_entities(group_id,entity_id) VALUES("+group.id+","+entityId+");"); + break; + } + default: + throw new UnsupportedOperationException("Unsupported identity type: "+member.getType()); + } + + transaction.commit(); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + catch(ClassCastException e) + { + throw new UnsupportedOperationException(e); + } + } + + @Slow + @Override + public void addManager(@NotNull Group group, @NotNull PlayerID manager) + throws DataSourceException, UnsupportedOperationException + { + try(Connection transaction = this.connection.transaction(); Statement stm = transaction.createStatement()) + { + try + { + int playerId = source.playerId(transaction, manager); + stm.executeUpdate("INSERT INTO minecity_group_managers(group_id,player_id) VALUES("+group.id+","+playerId+");"); + + transaction.commit(); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + catch(ClassCastException e) + { + throw new UnsupportedOperationException(e); + } + } + + @Slow + @Override + public void removeMember(@NotNull Group group, @NotNull Identity member) + throws DataSourceException, UnsupportedOperationException + { + try(Connection transaction = this.connection.transaction(); Statement stm = transaction.createStatement()) + { + try + { + switch(member.getType()) + { + case PLAYER: + { + int playerId = source.playerId(transaction, (PlayerID) member); + int changes = stm.executeUpdate("DELETE FROM minecity_group_players WHERE group_id="+group.id+" AND player_id="+playerId+";"); + if(changes != 1) + throw new DataSourceException("Expected 1 change, got "+changes+" changes"); + break; + } + case ENTITY: + { + int entityId = source.entityId(transaction, (EntityID) member); + int changes = stm.executeUpdate("INSERT INTO minecity_group_entities WHERE group_id="+group.id+" AND entity_id="+entityId+";"); + if(changes != 1) + throw new DataSourceException("Expected 1 change, got "+changes+" changes"); + break; + } + default: + throw new UnsupportedOperationException("Unsupported identity type: "+member.getType()); + } + + transaction.commit(); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + catch(ClassCastException e) + { + throw new UnsupportedOperationException(e); + } + } + + @Slow + @Override + public void removeManager(@NotNull Group group, @NotNull PlayerID manager) + throws DataSourceException, UnsupportedOperationException + { + try(Connection transaction = this.connection.transaction(); Statement stm = transaction.createStatement()) + { + try + { + int playerId = source.playerId(transaction, manager); + int changes = stm.executeUpdate("DELETE FROM minecity_group_managers WHERE group_id="+group.id+" AND player_id="+playerId+";"); + if(changes != 1) + throw new DataSourceException("Expected 1 change, got "+changes+" changes"); + + transaction.commit(); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + catch(ClassCastException e) + { + throw new UnsupportedOperationException(e); + } + } + + @Slow + @NotNull + @Override + public Collection loadIslands(City city) throws DataSourceException + { + try + { + Connection connection = this.connection.connect(); + int cityId = city.getId(); + try(PreparedStatement pst = connection.prepareStatement( + "SELECT c.island_id, MIN(x), MAX(x), MIN(z), MAX(z), COUNT(*), i.world_id, w.dim, w.world, w.`name` " + + "FROM minecity_chunks c " + + "INNER JOIN minecity_islands AS i ON c.island_id=i.island_id " + + "INNER JOIN minecity_world AS w ON i.world_id=w.world_id " + + "WHERE i.city_id = ? AND c.reserve=0 " + + "GROUP BY c.island_id" + )) + { + pst.setInt(1, cityId); + ArrayList islands = new ArrayList<>(3); + ResultSet result = pst.executeQuery(); + while(result.next()) + { + WorldDim world = source.world(result.getInt(7), ()->result.getInt(8), ()->result.getString(9), ()->result.getString(10)); + islands.add(new SQLIsland(this, permStorage, + result.getInt(1), result.getInt(2), result.getInt(3), + result.getInt(4), result.getInt(5), result.getInt(6), world, city + )); + } + islands.trimToSize(); + return islands; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @NotNull + @Override + public Collection loadGroups(@NotNull City city) throws DataSourceException + { + try + { + Connection connection = this.connection.connect(); + try(PreparedStatement groupPst = connection.prepareStatement( + "SELECT group_id, name, display_name FROM minecity_groups WHERE city_id=?" + ); + PreparedStatement playerPst = connection.prepareStatement( + "SELECT p.player_id, player_uuid, player_name " + + "FROM minecity_group_players gp " + + "INNER JOIN minecity_players p ON p.player_id = gp.player_id " + + "WHERE gp.group_id = ?" + ); + PreparedStatement entityPst = connection.prepareStatement( + "SELECT e.entity_id, entity_uuid, entity_name, entity_type " + + "FROM minecity_group_entities ge " + + "INNER JOIN minecity_entities e ON e.entity_id = ge.entity_id " + + "WHERE ge.group_id = ?" + ); + PreparedStatement managersPst = connection.prepareStatement( + "SELECT p.player_id, player_uuid, player_name " + + "FROM minecity_group_managers gm " + + "INNER JOIN minecity_players p ON p.player_id = gm.player_id " + + "WHERE gm.group_id = ?" + ) + ) + { + groupPst.setInt(1, city.getId()); + ResultSet groupResult = groupPst.executeQuery(); + List groups = new ArrayList<>(); + while(groupResult.next()) + { + int groupId = groupResult.getInt(1); + playerPst.setInt(1, groupId); + entityPst.setInt(1, groupId); + managersPst.setInt(1, groupId); + + List managers = new ArrayList<>(); + List> members = new ArrayList<>(); + + try(ResultSet managerResult = managersPst.executeQuery()) + { + while(managerResult.next()) + members.add(new PlayerID(managerResult.getInt("player_id"), + source.uuid(managerResult.getBytes("player_uuid")), + managerResult.getString("player_name") + )); + } + + try(ResultSet memberResult = playerPst.executeQuery()) + { + while(memberResult.next()) + members.add(new PlayerID(memberResult.getInt("player_id"), + source.uuid(memberResult.getBytes("player_uuid")), + memberResult.getString("player_name") + )); + } + + try(ResultSet memberResult = entityPst.executeQuery()) + { + while(memberResult.next()) + members.add(new EntityID(memberResult.getInt("entity_id"), + MinecraftEntity.Type.valueOf(memberResult.getString("entity_type")), + source.uuid(memberResult.getBytes("entity_uuid")), + memberResult.getString("entity_name") + )); + } + + groups.add(new Group(this, groupId, city, groupResult.getString(2), groupResult.getString(3), members, managers)); + } + + return groups; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @NotNull + @Override + public Island createIsland(@NotNull City city, @NotNull ChunkPos chunk) + throws DataSourceException, IllegalStateException + { + int cityId = city.getId(); + if(cityId <= 0) throw new IllegalStateException("The city is not registered"); + + try(Connection transaction = connection.transaction()) + { + try + { + SQLIsland island = new SQLIsland(this, permStorage, source.createIsland(transaction, cityId, chunk.world), chunk, city); + source.createClaim(transaction, island.id, chunk); + island.city = city; + + transaction.commit(); + + return island; + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @Override + public void claim(@NotNull Island island, @NotNull ChunkPos chunk) throws DataSourceException + { + SQLIsland sqlIsland = (SQLIsland) island; + try(Connection transaction = connection.transaction()) + { + try + { + source.createClaim(connection.connect(), sqlIsland.id, chunk); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + sqlIsland.add(chunk); + + source.mineCity.reloadChunk(chunk); + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @NotNull + @Override + @SuppressWarnings("OptionalGetWithoutIsPresent") + public Island claim(@NotNull Set islands, @NotNull ChunkPos chunk) + throws DataSourceException, IllegalStateException, NoSuchElementException + { + if(islands.size() == 1) + { + Island island = islands.iterator().next(); + claim(island, chunk); + return island; + } + + List sqlIslands = islands.stream().map(island -> (SQLIsland) island).collect(Collectors.toList()); + SQLIsland mainIsland = sqlIslands.stream().max((a, b) -> a.getChunkCount() - b.getChunkCount()).get(); + List merge = sqlIslands.stream().filter(island -> island != mainIsland).collect(Collectors.toList()); + try(Connection transaction = connection.transaction(); Statement stm = transaction.createStatement()) + { + try + { + StringBuilder sb = new StringBuilder(); + merge.forEach(island -> sb.append(island.id).append(", ")); + sb.setLength(sb.length()-2); + String array = sb.toString(); + + List chunksToUpdate = new ArrayList<>(); + try(ResultSet result = stm.executeQuery("SELECT c.world_id, c.x, c.z, w.dim, w.world, w.name " + + "FROM minecity_chunks c INNER JOIN minecity_world w ON c.world_id = w.world_id " + + "WHERE c.island_id IN("+array+");") + ){ + while(result.next()) + { + WorldDim world = source.world(result.getInt(1),()->result.getInt(4),()->result.getString(5),()->result.getString(6)); + chunksToUpdate.add(new ChunkPos(world, result.getInt(2), result.getInt(3))); + } + } + + stm.executeUpdate("UPDATE `minecity_chunks` SET `island_id`="+mainIsland.id+" WHERE `island_id` IN("+array+");"); + stm.executeUpdate("DELETE FROM `minecity_islands` WHERE `island_id` IN("+array+");"); + source.createClaim(transaction, mainIsland.id, chunk); + + transaction.commit(); + + mainIsland.add(chunk); + + merge.forEach(island -> { + mainIsland.minX = Math.min(mainIsland.minX, island.minX); + mainIsland.maxX = Math.max(mainIsland.maxX, island.maxX); + mainIsland.minZ = Math.min(mainIsland.minZ, island.minZ); + mainIsland.maxZ = Math.max(mainIsland.maxZ, island.maxZ); + mainIsland.chunkCount += island.chunkCount; + + island.minX = island.maxX = island.minZ = island.maxZ = island.chunkCount = 0; + }); + + chunksToUpdate.forEach((DBConsumer) source.mineCity::reloadChunk); + return mainIsland; + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @Override + public void setSpawn(@NotNull City city, @NotNull BlockPos spawn) throws DataSourceException, IllegalStateException + { + if(city.getSpawn().equals(spawn)) + return; + + int cityId = city.getId(); + if(cityId <= 0) throw new IllegalStateException("The city is not registered"); + + try + { + Connection connection = this.connection.connect(); + int worldId = source.worldId(connection, spawn.world); + + try(PreparedStatement pst = connection.prepareStatement( + "UPDATE `minecity_city` SET `spawn_world`=?, `spawn_x`=?, `spawn_y`=?, `spawn_z`=? WHERE `city_id`=?" + )) + { + pst.setInt(1, worldId); + pst.setInt(2, spawn.x); + //noinspection SuspiciousNameCombination + pst.setInt(3, spawn.y); + pst.setInt(4, spawn.z); + pst.setInt(5, cityId); + if(pst.executeUpdate() <= 0) + throw new DataSourceException("Tried to change spawn of "+ cityId+" from "+city.getSpawn()+" to "+spawn+" but nothing changed"); + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @Override + @SuppressWarnings("SuspiciousNameCombination") + public int createPlot(Plot plot) throws DataSourceException + { + try(Connection transaction = connection.transaction()) + { + try + { + int plotId; + try(PreparedStatement pst = transaction.prepareStatement( + "INSERT INTO minecity_plots(island_id,name,display_name,owner,spawn_x,spawn_y,spawn_z,shape,tax_accepted_flat,tax_accepted_percent,tax_applied_flat,tax_applied_percent,investment) " + + "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)", + Statement.RETURN_GENERATED_KEYS + )) + { + pst.setInt(1, plot.getIsland().getId()); + pst.setString(2, plot.getIdentityName()); + pst.setString(3, plot.getName()); + source.setNullableInt(pst, 4, source.playerId(transaction, plot.getOwner().orElse(null))); + BlockPos spawn = plot.getSpawn(); + pst.setInt(5, spawn.x); + pst.setInt(6, spawn.y); + pst.setInt(7, spawn.z); + pst.setBytes(8, plot.getShape().serializeBytes()); + pst.setDouble(9, plot.getAcceptedTax().getFlat()); + pst.setDouble(10, plot.getAcceptedTax().getPercent()); + pst.setDouble(11, plot.getAppliedTax().getFlat()); + pst.setDouble(12, plot.getAppliedTax().getPercent()); + pst.setDouble(13, plot.getInvestment()); + pst.executeUpdate(); + + ResultSet result = pst.getGeneratedKeys(); + result.next(); + plotId = result.getInt(1); + } + + transaction.commit(); + return plotId; + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @Override + public void setOwner(@NotNull Plot plot, @Nullable PlayerID owner) throws DataSourceException, IllegalStateException + { + try(Connection transaction = connection.transaction()) + { + try + { + try(PreparedStatement pst = transaction.prepareStatement( + "UPDATE minecity_plots SET owner=? WHERE plot_id=?" + )) + { + source.setNullableInt(pst, 1, source.playerId(transaction, owner)); + pst.setInt(2, plot.id); + source.executeUpdate(pst, 1); + } + + transaction.commit(); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @Override + public void setShape(@NotNull Plot plot, @NotNull Shape shape, BlockPos spawn, @NotNull Island newIsland) throws DataSourceException + { + try(Connection transaction = connection.transaction()) + { + try + { + try(PreparedStatement pst = transaction.prepareStatement( + "UPDATE minecity_plots SET shape=?, island_id=? WHERE plot_id=?" + )) + { + pst.setBytes(1, shape.serializeBytes()); + pst.setInt(2, newIsland.id); + pst.setInt(3, plot.id); + source.executeUpdate(pst, 1); + } + + setSpawn(transaction, plot, spawn); + + transaction.commit(); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @Override + public void setName(@NotNull Plot plot, @NotNull String identity, @NotNull String name) throws DataSourceException + { + try(Connection transaction = connection.transaction()) + { + try + { + try(PreparedStatement pst = transaction.prepareStatement( + "UPDATE minecity_plots SET `name`=?, `display_name`=? WHERE plot_id=?" + )) + { + pst.setString(1, identity); + pst.setString(2, name); + pst.setInt(3, plot.id); + source.executeUpdate(pst, 1); + } + + transaction.commit(); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @SuppressWarnings("SuspiciousNameCombination") + private void setSpawn(@NotNull Connection transaction, @NotNull Plot plot, @NotNull BlockPos spawn) + throws DataSourceException, SQLException + { + try(PreparedStatement pst = transaction.prepareStatement( + "UPDATE minecity_plots SET spawn_x=?, spawn_y=?, spawn_z=? WHERE plot_id=?" + )) + { + pst.setInt(1, spawn.x); + pst.setInt(2, spawn.y); + pst.setInt(3, spawn.z); + pst.setInt(4, plot.id); + source.executeUpdate(pst, 1); + } + } + + @Slow + @Override + public void setSpawn(@NotNull Plot plot, @NotNull BlockPos spawn) throws DataSourceException + { + if(!spawn.world.equals(plot.getIsland().world)) + throw new IllegalArgumentException("Different world!"); + + try(Connection transaction = connection.transaction()) + { + try + { + setSpawn(transaction, plot, spawn); + transaction.commit(); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @Override + public void deletePlot(@NotNull Plot plot) throws DataSourceException + { + try(Connection transaction = connection.transaction()) + { + try(PreparedStatement pst = transaction.prepareStatement( + "DELETE FROM minecity_plots WHERE plot_id=?" + )) + { + pst.setInt(1, plot.id); + source.executeUpdate(pst, 1); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + + transaction.commit(); + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @NotNull + @Override + public Set loadPlots(@NotNull Island island) throws DataSourceException + { + try + { + try(PreparedStatement pst = connection.connect().prepareStatement( + "SELECT plot_id,`name`,display_name,spawn_x,spawn_y,spawn_z,shape, player_id,player_uuid,player_name,perm_denial_message, " + + "tax_accepted_flat, tax_accepted_percent, tax_applied_flat, tax_applied_percent, investment, price " + + "FROM minecity_plots LEFT JOIN minecity_players ON player_id=owner " + + "WHERE island_id=?" + )) + { + pst.setInt(1, island.id); + ResultSet result = pst.executeQuery(); + if(!result.next()) + return Collections.emptySet(); + + // Memory optimization, caching common Tax instances + HashMap taxCache = new HashMap<>(6); + Tax t = island.getCity().getAppliedTax(); + taxCache.put(t, t); + t = island.getCity().mineCity.costs.plotTaxApplied; + taxCache.put(t, t); + BiFunction tax = (flat, percent)-> taxCache.computeIfAbsent(new Tax(flat, percent), Function.identity()); + + HashSet plots = new HashSet<>(3); + do + { + PlayerID owner; + int ownerId = result.getInt(8); + if(ownerId > 0) + owner = PlayerID.get(source.uuid(result.getBytes(9)), result.getString(10)); + else + owner = null; + + Message denial; + String str = result.getString(11); + if(str == null) + denial = null; + else + denial = new Message("", "${msg}", new Object[]{"msg",str}); + + plots.add(new Plot(source.mineCity, this, permStorage, result.getInt(1), island, result.getString(2), result.getString(3), owner, + new BlockPos(island.world, result.getInt(4), result.getInt(5), result.getInt(6)), + Shape.deserializeBytes(result.getBytes(7)), denial, + tax.apply(result.getDouble("tax_accepted_flat"), result.getDouble("tax_accepted_percent")), + tax.apply(result.getDouble("tax_applied_flat"), result.getDouble("tax_applied_percent")), + result.getDouble("investment"), result.getDouble("price") + )); + } while(result.next()); + + return plots; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } +} diff --git a/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLConnection.java b/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLConnection.java index faf3ff20..9ae35fec 100644 --- a/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLConnection.java +++ b/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLConnection.java @@ -1,92 +1,92 @@ -package br.com.gamemods.minecity.datasource.sql; - -import br.com.gamemods.minecity.api.Slow; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; - -public class SQLConnection -{ - @NotNull - private String url; - @Nullable - private String user; - @Nullable - private byte[] pass; - private Connection connection; - public int checkTimeout = 50; - public int minCheckInterval = 5000; - private long lastCheck; - private boolean closed; - - public SQLConnection(@NotNull String url, @Nullable String user, @Nullable byte[] passwd) - { - this.url = url; - this.user = user; - this.pass = passwd; - } - - @Slow - public synchronized Connection connect() throws SQLException - { - if(closed) - throw new SQLException(new IllegalStateException("The SQL provider is closed")); - - if(connection != null) - { - try - { - if(!connection.isClosed()) - { - if(System.currentTimeMillis() - lastCheck < minCheckInterval) - return connection; - else if(connection.isValid(checkTimeout)) - { - lastCheck = System.currentTimeMillis(); - return connection; - } - } - } - catch(NullPointerException | SQLException ignored) - {} - } - - return connection = DriverManager.getConnection(url, user, pass == null? null : new String(pass)); - } - - @Slow - public synchronized void disconnect() throws SQLException - { - try - { - if(connection != null) - connection.close(); - } - catch(SQLException e) - { - connection = null; - throw e; - } - } - - @Slow - public Connection transaction() throws SQLException - { - if(closed) - throw new SQLException(new IllegalStateException("The SQL provider is closed")); - - Connection connection = DriverManager.getConnection(url, user, pass == null? null : new String(pass)); - connection.setAutoCommit(false); - return connection; - } - - @Slow - public void close() throws SQLException - { - closed = true; - disconnect(); - } -} +package br.com.gamemods.minecity.datasource.sql; + +import br.com.gamemods.minecity.api.Slow; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +public class SQLConnection +{ + @NotNull + private String url; + @Nullable + private String user; + @Nullable + private byte[] pass; + private Connection connection; + public int checkTimeout = 50; + public int minCheckInterval = 5000; + private long lastCheck; + private boolean closed; + + public SQLConnection(@NotNull String url, @Nullable String user, @Nullable byte[] passwd) + { + this.url = url; + this.user = user; + this.pass = passwd; + } + + @Slow + public synchronized Connection connect() throws SQLException + { + if(closed) + throw new SQLException(new IllegalStateException("The SQL provider is closed")); + + if(connection != null) + { + try + { + if(!connection.isClosed()) + { + if(System.currentTimeMillis() - lastCheck < minCheckInterval) + return connection; + else if(connection.isValid(checkTimeout)) + { + lastCheck = System.currentTimeMillis(); + return connection; + } + } + } + catch(NullPointerException | SQLException ignored) + {} + } + + return connection = DriverManager.getConnection(url, user, pass == null? null : new String(pass)); + } + + @Slow + public synchronized void disconnect() throws SQLException + { + try + { + if(connection != null) + connection.close(); + } + catch(SQLException e) + { + connection = null; + throw e; + } + } + + @Slow + public Connection transaction() throws SQLException + { + if(closed) + throw new SQLException(new IllegalStateException("The SQL provider is closed")); + + Connection connection = DriverManager.getConnection(url, user, pass == null? null : new String(pass)); + connection.setAutoCommit(false); + return connection; + } + + @Slow + public void close() throws SQLException + { + closed = true; + disconnect(); + } +} diff --git a/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLIsland.java b/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLIsland.java index 3a30cb70..71900ce4 100644 --- a/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLIsland.java +++ b/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLIsland.java @@ -1,123 +1,123 @@ -package br.com.gamemods.minecity.datasource.sql; - -import br.com.gamemods.minecity.api.world.ChunkPos; -import br.com.gamemods.minecity.api.world.WorldDim; -import br.com.gamemods.minecity.datasource.api.DataSourceException; -import br.com.gamemods.minecity.datasource.api.ICityStorage; -import br.com.gamemods.minecity.datasource.api.IExceptPermissionStorage; -import br.com.gamemods.minecity.structure.City; -import br.com.gamemods.minecity.structure.Inconsistency; -import br.com.gamemods.minecity.structure.Island; -import br.com.gamemods.minecity.structure.Plot; -import org.jetbrains.annotations.NotNull; - -import java.util.Collections; -import java.util.Set; - -final class SQLIsland extends Island -{ - int minX; - int maxX; - int minZ; - int maxZ; - int chunkCount; - - @NotNull - City city; - - SQLIsland(City city, ICityStorage storage, IExceptPermissionStorage permissionStorage, int id, - int minX, int maxX, int minZ, int maxZ, int chunkCount, @NotNull WorldDim world, Set plots) - { - super(city, storage, permissionStorage, id, world, plots); - this.minX = minX; - this.maxX = maxX; - this.minZ = minZ; - this.maxZ = maxZ; - this.chunkCount = chunkCount; - this.city = Inconsistency.getInconsistentCity(); - } - - SQLIsland(ICityStorage storage, IExceptPermissionStorage permissionStorage, int id, - int minX, int maxX, int minZ, int maxZ, int chunkCount, @NotNull WorldDim world, @NotNull City city) - throws DataSourceException - { - super(city, storage, permissionStorage, id, world); - this.minX = minX; - this.maxX = maxX; - this.minZ = minZ; - this.maxZ = maxZ; - this.chunkCount = chunkCount; - this.city = city; - } - - SQLIsland(ICityStorage storage, IExceptPermissionStorage permissionStorage, int id, ChunkPos chunk, @NotNull City city) - { - super(city, storage, permissionStorage, id, chunk.world, Collections.emptySet()); - minX = maxX = chunk.x; - minZ = maxZ = chunk.z; - chunkCount = 1; - this.city = city; - } - - void add(ChunkPos chunk) - { - minX = Math.min(minX, chunk.x); - maxX = Math.max(maxX, chunk.x); - minZ = Math.min(minZ, chunk.z); - maxZ = Math.max(maxZ, chunk.z); - chunkCount++; - } - - void relocate(Plot plot, SQLIsland to) - { - String id = plot.getIdentityName(); - plots.remove(id, plot); - to.plots.put(id, plot); - plot.relocate(to); - } - - @Override - public int getSizeX() - { - return chunkCount == 0? 0 : maxX - minX + 1; - } - - @Override - public int getSizeZ() - { - return chunkCount == 0? 0 : maxZ - minZ + 1; - } - - @Override - public int getChunkCount() - { - return chunkCount; - } - - @Override - public boolean equals(Object o) - { - if(this == o) return true; - if(o == null || getClass() != o.getClass()) return false; - - SQLIsland sqlIsland = (SQLIsland) o; - return id == sqlIsland.id; - - } - - @Override - public int hashCode() - { - return id; - } - - @Override - public String toString() - { - return "SQLIsland{" + - "id=" + id + - ", world=" + world + - ", city=" + city + - '}'; - } -} +package br.com.gamemods.minecity.datasource.sql; + +import br.com.gamemods.minecity.api.world.ChunkPos; +import br.com.gamemods.minecity.api.world.WorldDim; +import br.com.gamemods.minecity.datasource.api.DataSourceException; +import br.com.gamemods.minecity.datasource.api.ICityStorage; +import br.com.gamemods.minecity.datasource.api.IExceptPermissionStorage; +import br.com.gamemods.minecity.structure.City; +import br.com.gamemods.minecity.structure.Inconsistency; +import br.com.gamemods.minecity.structure.Island; +import br.com.gamemods.minecity.structure.Plot; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.Set; + +final class SQLIsland extends Island +{ + int minX; + int maxX; + int minZ; + int maxZ; + int chunkCount; + + @NotNull + City city; + + SQLIsland(City city, ICityStorage storage, IExceptPermissionStorage permissionStorage, int id, + int minX, int maxX, int minZ, int maxZ, int chunkCount, @NotNull WorldDim world, Set plots) + { + super(city, storage, permissionStorage, id, world, plots); + this.minX = minX; + this.maxX = maxX; + this.minZ = minZ; + this.maxZ = maxZ; + this.chunkCount = chunkCount; + this.city = Inconsistency.getInconsistentCity(); + } + + SQLIsland(ICityStorage storage, IExceptPermissionStorage permissionStorage, int id, + int minX, int maxX, int minZ, int maxZ, int chunkCount, @NotNull WorldDim world, @NotNull City city) + throws DataSourceException + { + super(city, storage, permissionStorage, id, world); + this.minX = minX; + this.maxX = maxX; + this.minZ = minZ; + this.maxZ = maxZ; + this.chunkCount = chunkCount; + this.city = city; + } + + SQLIsland(ICityStorage storage, IExceptPermissionStorage permissionStorage, int id, ChunkPos chunk, @NotNull City city) + { + super(city, storage, permissionStorage, id, chunk.world, Collections.emptySet()); + minX = maxX = chunk.x; + minZ = maxZ = chunk.z; + chunkCount = 1; + this.city = city; + } + + void add(ChunkPos chunk) + { + minX = Math.min(minX, chunk.x); + maxX = Math.max(maxX, chunk.x); + minZ = Math.min(minZ, chunk.z); + maxZ = Math.max(maxZ, chunk.z); + chunkCount++; + } + + void relocate(Plot plot, SQLIsland to) + { + String id = plot.getIdentityName(); + plots.remove(id, plot); + to.plots.put(id, plot); + plot.relocate(to); + } + + @Override + public int getSizeX() + { + return chunkCount == 0? 0 : maxX - minX + 1; + } + + @Override + public int getSizeZ() + { + return chunkCount == 0? 0 : maxZ - minZ + 1; + } + + @Override + public int getChunkCount() + { + return chunkCount; + } + + @Override + public boolean equals(Object o) + { + if(this == o) return true; + if(o == null || getClass() != o.getClass()) return false; + + SQLIsland sqlIsland = (SQLIsland) o; + return id == sqlIsland.id; + + } + + @Override + public int hashCode() + { + return id; + } + + @Override + public String toString() + { + return "SQLIsland{" + + "id=" + id + + ", world=" + world + + ", city=" + city + + '}'; + } +} diff --git a/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLSource.java b/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLSource.java index 93d4d34b..c5c4118d 100644 --- a/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLSource.java +++ b/Core/src/main/java/br/com/gamemods/minecity/datasource/sql/SQLSource.java @@ -1,861 +1,861 @@ -package br.com.gamemods.minecity.datasource.sql; - -import br.com.gamemods.minecity.MineCity; -import br.com.gamemods.minecity.MineCityConfig; -import br.com.gamemods.minecity.api.PlayerID; -import br.com.gamemods.minecity.api.Slow; -import br.com.gamemods.minecity.api.command.Message; -import br.com.gamemods.minecity.api.permission.*; -import br.com.gamemods.minecity.api.world.BlockPos; -import br.com.gamemods.minecity.api.world.ChunkPos; -import br.com.gamemods.minecity.api.world.WorldDim; -import br.com.gamemods.minecity.datasource.api.CityCreationResult; -import br.com.gamemods.minecity.datasource.api.DataSourceException; -import br.com.gamemods.minecity.datasource.api.IDataSource; -import br.com.gamemods.minecity.datasource.api.unchecked.DBSupplier; -import br.com.gamemods.minecity.datasource.api.unchecked.UncheckedDataSourceException; -import br.com.gamemods.minecity.economy.Tax; -import br.com.gamemods.minecity.structure.*; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.ByteBuffer; -import java.sql.*; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import static br.com.gamemods.minecity.api.StringUtil.identity; - -public class SQLSource implements IDataSource -{ - private static final int VERSION = 7; - - @NotNull - public final MineCity mineCity; - @NotNull - private final SQLConnection connection; - @NotNull - private final SQLCityStorage cityStorage; - @NotNull - private final SQLPermStorage permStorage; - @NotNull - final Map cityMap = new HashMap<>(); - final Map worldDimMap = new ConcurrentHashMap<>(3); - final Set cityNames = new HashSet<>(); - final Map> groupNames = new HashMap<>(); - - public SQLSource(@NotNull MineCity mineCity, @NotNull MineCityConfig config) - { - this.mineCity = mineCity; - connection = new SQLConnection(config.dbUrl, config.dbUser, config.dbPass != null? config.dbPass.clone() : null); - if(config.dbPass != null) - Arrays.fill(config.dbPass, (byte) 0); - - permStorage = new SQLPermStorage(this, connection); - cityStorage = new SQLCityStorage(this, connection, permStorage); - } - - protected WorldDim world(int id, DBSupplier dim, DBSupplier dir, DBSupplier name) - { - WorldDim world = worldDimMap.get(id); - if(world != null) - return world; - - int dimI = dim.get(); - String dirS = dir.get(); - world = mineCity.worldProvider.map(p-> p.getWorld(dimI, dirS)).orElseGet(()-> new WorldDim(dimI, dirS)); - - world.setDataSourceId(id); - worldDimMap.put(id, world); - - if(name != null) - world.name = name.get(); - - return world; - } - - @Slow - private Optional loadCity(Connection connection, int id, @Nullable String identity) throws SQLException, DataSourceException - { - synchronized(cityMap) - { - try(PreparedStatement pst = connection.prepareStatement( - "SELECT `c`.`name`, `owner`, `o`.`player_uuid`, `o`.`player_name`, `spawn_world`, `spawn_x`, `spawn_y`, `spawn_z`, " + - "`w`.`dim`, `w`.`world`, `w`.`name`, `display_name`, c.`perm_denial_message`, `city_id`," + - "`tax_applied_flat`, `tax_applied_percent`, `investment`, `price` " + - "FROM `minecity_city` AS `c` " + - "LEFT JOIN `minecity_players` AS `o` ON `owner` = `o`.`player_id` "+ - "LEFT JOIN `minecity_world` AS `w` ON `spawn_world` = `w`.`world_id` "+ - " WHERE "+(identity == null?"`city_id`=?":"`c`.`name`=?") - )) - { - if(identity == null) - pst.setInt(1, id); - else - pst.setString(1, identity); - - ResultSet result = pst.executeQuery(); - if(!result.next()) - return Optional.empty(); - - PlayerID owner; - int ownerId = result.getInt(2); - if(ownerId <= 0) owner = null; - else - owner = new PlayerID(ownerId, uuid(result.getBytes(3)), result.getString(4)); - - WorldDim world = world(result.getInt(5), ()->result.getInt(9), ()->result.getString(10), ()->result.getString(11)); - BlockPos spawn = new BlockPos(world, result.getInt(6), result.getInt(7), result.getInt(8)); - - String name = result.getString(1); - String displayName = result.getString(12); - - String str = result.getString("perm_denial_message"); - Message message = str == null? null : new Message("", "${msg}", new Object[]{"msg",str}); - id = result.getInt("city_id"); - Tax tax = new Tax(result.getDouble("tax_applied_flat"), result.getDouble("tax_applied_percent")); - if(tax.equals(mineCity.costs.cityTaxApplied)) - tax = mineCity.costs.cityTaxApplied; - double investment = result.getDouble("investment"); - double price = result.getDouble("price"); - pst.close(); - - City city = new City(mineCity, name, displayName, owner, spawn, id, cityStorage, permStorage, message, tax, investment, price); - cityMap.put(id, city); - return Optional.of(city); - } - } - } - - void executeUpdate(PreparedStatement pst, int expected) throws DataSourceException, SQLException - { - int changes = pst.executeUpdate(); - if(changes != expected) - throw new DataSourceException("Expected "+expected+" but got "+changes); - } - - private int insertWorld(Connection connection, WorldDim world) throws SQLException - { - try(PreparedStatement pst = connection.prepareStatement( - "INSERT INTO `minecity_world`(`dim`,`world`,`name`) VALUES(?,?,?)", - Statement.RETURN_GENERATED_KEYS - )) - { - pst.setInt(1, world.dim); - pst.setString(2, world.dir); - setNullableString(pst, 3, world.name); - pst.executeUpdate(); - ResultSet keys = pst.getGeneratedKeys(); - keys.next(); - return keys.getInt(1); - } - } - - @Slow - int worldId(Connection connection, WorldDim world) throws DataSourceException - { - int dataSourceId = world.getDataSourceId(); - if(dataSourceId > 0) return dataSourceId; - - int id = 0; - try - { - try(PreparedStatement pst = connection.prepareStatement( - "SELECT `world_id` FROM `minecity_world` WHERE `dim`=? AND `world`=?" - )) - { - pst.setInt(1, world.dim); - pst.setString(2, world.dir); - ResultSet result = pst.executeQuery(); - if(result.next()) - world.setDataSourceId(id = result.getInt(1)); - } - - if(id <= 0) - insertWorld(connection, world); - - world.setDataSourceId(id); - worldDimMap.putIfAbsent(id, world); - return id; - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Contract("null->null;!null->!null") - byte[] uuid(UUID uuid) - { - if(uuid == null) - return null; - - byte[] bytes = new byte[16]; - ByteBuffer buffer = ByteBuffer.wrap(bytes); - buffer.putLong(uuid.getMostSignificantBits()); - buffer.putLong(uuid.getLeastSignificantBits()); - return bytes; - } - - @Contract("null->null;!null->!null") - UUID uuid(byte[] bytes) throws DataSourceException - { - if(bytes == null) - return null; - - try - { - ByteBuffer bb = ByteBuffer.wrap(bytes); - long firstLong = bb.getLong(); - long secondLong = bb.getLong(); - return new UUID(firstLong, secondLong); - } - catch(Exception e) - { - throw new DataSourceException("Bad UUID", e); - } - } - - void setNullableInt(PreparedStatement pst, int field, int val) throws SQLException - { - if(val == 0) - pst.setNull(field, Types.INTEGER); - else - pst.setInt(field, val); - } - - void setNullableString(PreparedStatement pst, int field, String val) throws SQLException - { - if(val == null) - pst.setNull(field, Types.VARCHAR); - else - pst.setString(field, val); - } - - @Slow - int playerId(Connection connection, @Nullable OptionalPlayer player) throws DataSourceException - { - PlayerID playerId; - if(player == null || (playerId = player.player()) == null) return 0; - int id = player.getDataSourceId(); - if(id > 0) return id; - - try - { - try(PreparedStatement pst = connection.prepareStatement( - "SELECT `player_id` FROM `minecity_players` WHERE `player_uuid`=?" - )) - { - pst.setBytes(1, uuid(playerId.uniqueId)); - ResultSet result = pst.executeQuery(); - if(result.next()) - { - id = result.getInt(1); - playerId.setDataSourceId(id); - return id; - } - } - - try(PreparedStatement pst = connection.prepareStatement( - "INSERT INTO `minecity_players`(`player_uuid`, `player_name`) VALUES(?,?)" - , Statement.RETURN_GENERATED_KEYS - )) - { - pst.setBytes(1, uuid(playerId.uniqueId)); - pst.setString(2, playerId.getName()); - pst.executeUpdate(); - ResultSet keys = pst.getGeneratedKeys(); - keys.next(); - id = keys.getInt(1); - playerId.setDataSourceId(id); - return id; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - int entityId(Connection connection, @Nullable EntityID entity) throws DataSourceException - { - if(entity == null) return 0; - int id = entity.getDataSourceId(); - if(id > 0) return id; - - try - { - try(PreparedStatement pst = connection.prepareStatement( - "SELECT `entity_id` FROM `minecity_entities` WHERE `entity_uuid`=?" - )) - { - pst.setBytes(1, uuid(entity.uniqueId)); - ResultSet result = pst.executeQuery(); - if(result.next()) - { - id = result.getInt(1); - entity.setDataSourceId(id); - return id; - } - } - - try(PreparedStatement pst = connection.prepareStatement( - "INSERT INTO `minecity_entities`(`entity_uuid`, `entity_name`, entity_type) VALUES(?,?,?)" - , Statement.RETURN_GENERATED_KEYS - )) - { - pst.setBytes(1, uuid(entity.uniqueId)); - pst.setString(2, entity.getName()); - pst.setString(3, entity.getEntityType().name()); - pst.executeUpdate(); - ResultSet keys = pst.getGeneratedKeys(); - keys.next(); - id = keys.getInt(1); - entity.setDataSourceId(id); - return id; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - private City city(Connection connection, int cityId) throws SQLException, DataSourceException - { - synchronized(cityMap) - { - City city = cityMap.get(cityId); - if(city != null) - return city; - - return loadCity(connection, cityId, null).orElseThrow(()-> new DataSourceException("City ID "+cityId+" not found")); - } - } - - @Slow - @Nullable - @Override - public ClaimedChunk getCityChunk(@NotNull ChunkPos pos) throws DataSourceException - { - try - { - Connection connection = this.connection.connect(); - try(PreparedStatement pst = connection.prepareStatement( - "SELECT `i`.`city_id`, `i`.`island_id`, reserve FROM `minecity_chunks` AS `c` " + - "INNER JOIN `minecity_world` AS `w` ON `c`.`world_id`=`w`.`world_id` " + - "INNER JOIN `minecity_islands` AS `i` ON `c`.`island_id`=`i`.`island_id` "+ - "WHERE `w`.`dim`=? AND `w`.`world`=? AND `c`.`x`=? AND `c`.`z`=?;" - )) - { - pst.setInt(1, pos.world.dim); - pst.setString(2, pos.world.dir); - pst.setInt(3, pos.x); - pst.setInt(4, pos.z); - ResultSet result = pst.executeQuery(); - if(!result.next()) - return null; - int cityId = result.getInt(1); - int islandId = result.getInt(2); - boolean reserve = result.getBoolean(3); - pst.close(); - - City city = city(connection, cityId); - Island island = city.getIsland(islandId); - return new ClaimedChunk(island != null? island : Inconsistency.getInconsistentIsland(), pos, reserve); - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - catch(UncheckedDataSourceException e) - { - throw e.getCause(); - } - } - - @Slow - int createIsland(Connection transaction, int cityId, WorldDim world) throws DataSourceException, SQLException - { - int worldId = worldId(transaction, world); - int islandId; - try(PreparedStatement pst = transaction.prepareStatement( - "INSERT INTO `minecity_islands`(world_id, city_id) VALUES(?,?)", - Statement.RETURN_GENERATED_KEYS - )) - { - pst.setInt(1, worldId); - pst.setInt(2, cityId); - pst.executeUpdate(); - ResultSet keys = pst.getGeneratedKeys(); - keys.next(); - islandId = keys.getInt(1); - } - - return islandId; - } - - @Slow - void createClaim(Connection connection, int islandId, ChunkPos chunk) throws SQLException, DataSourceException - { - int worldId = worldId(connection, chunk.world); - try(PreparedStatement pst = connection.prepareStatement( - "DELETE FROM minecity_chunks WHERE world_id=? AND x=? AND z=? AND reserve=1" - )) - { - pst.setInt(1, worldId); - pst.setInt(2, chunk.x); - pst.setInt(3, chunk.z); - pst.executeUpdate(); - } - try(PreparedStatement pst = connection.prepareStatement( - "INSERT INTO `minecity_chunks`(world_id, x, z, island_id, reserve) VALUES(?,?,?,?,0)" - )) - { - pst.setInt(1, worldId); - pst.setInt(2, chunk.x); - pst.setInt(3, chunk.z); - pst.setInt(4, islandId); - if(pst.executeUpdate() <= 0) - throw new DataSourceException("Failed to claim the spawn chunk"); - } - } - - @Nullable - @Override - public String checkNameConflict(@NotNull String name) - { - name = identity(name); - for(String cityName : cityNames) - if(identity(cityName).equals(name)) - return cityName; - - return null; - } - - @Slow - @NotNull - @Override - public CityCreationResult createCity(@NotNull City city) throws DataSourceException, IllegalStateException - { - if(city.getId() > 0) - throw new IllegalStateException(); - - try - { - BlockPos spawn = city.getSpawn(); - ChunkPos spawnChunk = spawn.getChunk(); - ClaimedChunk claim = getCityChunk(spawnChunk); - if(claim != null) - throw new IllegalStateException("The chunk " + spawnChunk + " is already claimed: " + claim); - - int islandId; - try(Connection connection = this.connection.transaction()) - { - try - { - int worldId = worldId(connection, spawn.world); - int cityId; - try(PreparedStatement pst = connection.prepareStatement( - "INSERT INTO `minecity_city`(name, owner, spawn_world, spawn_x, spawn_y, spawn_z, display_name, tax_applied_flat, tax_applied_percent, investment) " + - "VALUES ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )", - Statement.RETURN_GENERATED_KEYS - )) - { - pst.setString(1, city.getIdentityName()); - setNullableInt(pst, 2, playerId(connection, city.owner())); - pst.setInt(3, worldId); - pst.setInt(4, spawn.x); - //noinspection SuspiciousNameCombination - pst.setInt(5, spawn.y); - pst.setInt(6, spawn.z); - pst.setString(7, city.getName()); - pst.setDouble(8, city.getAppliedTax().getFlat()); - pst.setDouble(9, city.getAppliedTax().getPercent()); - pst.setDouble(10, city.getInvestment()); - pst.executeUpdate(); - ResultSet keys = pst.getGeneratedKeys(); - keys.next(); - cityId = keys.getInt(1); - city.setId(cityId); - cityMap.put(cityId, city); - } - - islandId = createIsland(connection, cityId, spawnChunk.world); - createClaim(connection, islandId, spawnChunk); - connection.commit(); - cityNames.add(city.getName()); - } - catch(Exception e) - { - connection.rollback(); - throw e; - } - } - - return new CityCreationResult(cityStorage, permStorage, - new SQLIsland(cityStorage, permStorage, islandId, spawnChunk, city), - Collections.emptyList() - ); - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @Override - public void initDB() throws DataSourceException, IOException - { - try(Connection transaction = connection.transaction()) - { - try(Statement stm = transaction.createStatement()) - { - ResultSet result; - int version; - try - { - result = stm.executeQuery("SELECT `value` FROM `minecity_setup` WHERE `property`='version';"); - result.next(); - version = result.getInt(1); - result.close(); - } - catch(SQLException e) - { - System.out.println("[MineCity] Installing the SQL database version "+VERSION); - ScriptRunner runner = new ScriptRunner(transaction, false, true); - runner.setLogWriter(null); - runner.runScript(new InputStreamReader( - getClass().getResourceAsStream("/assets/minecity/db/setup.sql"), "UTF-8" - )); - transaction.commit(); - return; - } - - if(version > VERSION) - throw new DataSourceException("Unsupported database version: "+version); - - if(version < VERSION) - { - System.out.println("[MineCity] Starting the database upgrade from "+version+" to "+VERSION); - for(; version < VERSION; version++) - { - System.out.println("[MineCity] Upgrading to version "+(version+1)); - ScriptRunner runner = new ScriptRunner(transaction, false, true); - runner.setLogWriter(null); - runner.runScript(new InputStreamReader( - getClass().getResourceAsStream("/assets/minecity/db/update_"+version+".sql"), "UTF-8" - )); - } - - transaction.commit(); - System.out.println("[MineCity] The database was successfully upgraded"); - } - - result = stm.executeQuery("SELECT `display_name` FROM `minecity_city` "); - while(result.next()) - cityNames.add(result.getString(1)); - result.close(); - - result = stm.executeQuery("SELECT c.name, g.name FROM minecity_groups g INNER JOIN minecity_city c ON c.city_id = g.city_id"); - while(result.next()) - groupNames.computeIfAbsent(result.getString(1), n-> new HashSet<>(1)).add(result.getString(2)); - } - catch(Exception e) - { - transaction.rollback(); - throw e; - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @NotNull - @Override - public Optional getCityByName(@NotNull String name) throws DataSourceException - { - name = identity(name); - if(name.length() < 3) - return Optional.empty(); - - synchronized(cityMap) - { - for(City city : cityMap.values()) - if(city.getIdentityName().equals(name)) - return Optional.of(city); - - try - { - return loadCity(connection.connect(), 0, name); - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - } - - @NotNull - @Override - public Set getEntityGroups(Identity identity) throws DataSourceException - { - try - { - switch(identity.getType()) - { - case PLAYER: - Connection connection = this.connection.connect(); - try(PreparedStatement pst = connection.prepareStatement( - "SELECT g.group_id, g.city_id, g.display_name, c.display_name AS home " + - "FROM minecity_group_players gp " + - "INNER JOIN minecity_groups g ON g.group_id = gp.group_id " + - "INNER JOIN minecity_city c ON c.city_id = g.city_id " + - "WHERE gp.player_id=?" - )) - { - pst.setInt(1, playerId(connection, (PlayerID) identity)); - ResultSet result = pst.executeQuery(); - Set set = new HashSet<>(2); - while(result.next()) - { - int groupId = result.getInt(1); - int cityId = result.getInt(2); - String name = result.getString(3); - String home = result.getString(4); - GroupID group = Optional.ofNullable(cityMap.get(cityId)) - .map(c-> c.getGroup(groupId)).map(Group::getIdentity) - .orElseGet(()-> new GroupID(groupId, name, home, cityId)) - ; - set.add(group); - } - - return set; - } - - case ENTITY: - connection = this.connection.connect(); - int id = identity.getDataSourceId(); - try(PreparedStatement pst = connection.prepareStatement( - "SELECT g.group_id, g.city_id, g.display_name, c.display_name AS home " + - "FROM minecity_group_entities ge " + - "INNER JOIN minecity_groups g ON g.group_id = ge.group_id " + - "INNER JOIN minecity_city c ON c.city_id = g.city_id " + - (id > 0 ? "WHERE ge.entity_id = ?" : - "INNER JOIN minecity_entities e ON ge.entity_id = e.entity_id " + - "WHERE e.entity_uuid = ?") - )) - { - if(id > 0) - pst.setInt(1, id); - else - pst.setBytes(1, uuid(((EntityID)identity).getUniqueId())); - - ResultSet result = pst.executeQuery(); - Set set = new HashSet<>(2); - while(result.next()) - { - int groupId = result.getInt(1); - int cityId = result.getInt(2); - String name = result.getString(3); - String home = result.getString(4); - GroupID group = Optional.ofNullable(cityMap.get(cityId)) - .map(c-> c.getGroup(groupId)).map(Group::getIdentity) - .orElseGet(()-> new GroupID(groupId, name, home, cityId)) - ; - set.add(group); - } - - return set; - } - - default: - return Collections.emptySet(); - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @NotNull - @Override - public Optional getPlayer(@NotNull String name) throws DataSourceException - { - try(PreparedStatement pst = connection.connect().prepareStatement( - "SELECT player_id, player_uuid, player_name FROM minecity_players WHERE player_name=?" - )) - { - pst.setString(1, name); - ResultSet result = pst.executeQuery(); - if(!result.next()) - return Optional.empty(); - return Optional.of(new PlayerID(result.getInt(1), uuid(result.getBytes(2)), result.getString(3))); - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @NotNull - @Override - public IslandArea getArea(@NotNull Island island) - throws DataSourceException, ClassCastException, IllegalArgumentException - { - SQLIsland sqlIsland = (SQLIsland) island; - - try - { - Connection connection = this.connection.connect(); - try(PreparedStatement pst = connection.prepareStatement( - "SELECT x, z FROM minecity_chunks WHERE island_id=? AND world_id=? AND reserve=0" - )) - { - pst.setInt(1, sqlIsland.id); - pst.setInt(2, worldId(connection, sqlIsland.world)); - ResultSet result = pst.executeQuery(); - List list = new ArrayList<>(); - while(result.next()) - list.add(new ChunkPos(sqlIsland.world, result.getInt(1), result.getInt(2))); - - return new IslandArea(island, list); - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @NotNull - @Override - public Nature getNature(@NotNull WorldDim world) throws DataSourceException - { - try - { - int id = world.getDataSourceId(); - Connection connection = this.connection.connect(); - try(PreparedStatement pst = connection.prepareStatement( - "SELECT world_id, `name`, city_creations, perm_denial_message " + - "FROM minecity_world " + - "WHERE "+(id > 0? "world_id=?":"dim=? AND world=?") - )) - { - if(id > 0) - pst.setInt(1, id); - else - { - pst.setInt(1, world.dim); - pst.setString(2, world.dir); - } - - ResultSet result = pst.executeQuery(); - if(result.next()) - { - if(id == 0) - world.setDataSourceId(result.getInt(1)); - - world.name = result.getString(2); - - boolean cityCreation = result.getBoolean(3); - - String str = result.getString(4); - Message message; - if(str == null) - message = null; - else - message = Message.string(str); - pst.close(); - - return new Nature(mineCity, world, message, permStorage, permStorage, !cityCreation); - } - } - - if(id == 0) - world.setDataSourceId(insertWorld(connection, world)); - - return new Nature(mineCity, world, permStorage, permStorage); - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @NotNull - @Override - public Supplier> cityNameSupplier() - { - return cityNames::stream; - } - - @NotNull - @Override - public Optional> getGroupNames(@NotNull String cityName) - { - Set set = groupNames.get(identity(cityName)); - if(set == null) - return Optional.empty(); - return Optional.of(Collections.unmodifiableSet(set)); - } - - @NotNull - @Override - public Map> getGroups() - { - return Collections.unmodifiableMap(groupNames); - } - - @Override - public int getCityCount(PlayerID playerId) throws DataSourceException - { - try - { - Connection connection = this.connection.connect(); - try(PreparedStatement pst = connection.prepareStatement( - "SELECT count(*) FROM `minecity_city` WHERE `owner`=?" - )) - { - pst.setInt(1, playerId(connection, playerId)); - ResultSet result = pst.executeQuery(); - result.next(); - return result.getInt(1); - } - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } - - @Slow - @Override - public void close() throws DataSourceException - { - try - { - connection.close(); - } - catch(SQLException e) - { - throw new DataSourceException(e); - } - } -} +package br.com.gamemods.minecity.datasource.sql; + +import br.com.gamemods.minecity.MineCity; +import br.com.gamemods.minecity.MineCityConfig; +import br.com.gamemods.minecity.api.PlayerID; +import br.com.gamemods.minecity.api.Slow; +import br.com.gamemods.minecity.api.command.Message; +import br.com.gamemods.minecity.api.permission.*; +import br.com.gamemods.minecity.api.world.BlockPos; +import br.com.gamemods.minecity.api.world.ChunkPos; +import br.com.gamemods.minecity.api.world.WorldDim; +import br.com.gamemods.minecity.datasource.api.CityCreationResult; +import br.com.gamemods.minecity.datasource.api.DataSourceException; +import br.com.gamemods.minecity.datasource.api.IDataSource; +import br.com.gamemods.minecity.datasource.api.unchecked.DBSupplier; +import br.com.gamemods.minecity.datasource.api.unchecked.UncheckedDataSourceException; +import br.com.gamemods.minecity.economy.Tax; +import br.com.gamemods.minecity.structure.*; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.ByteBuffer; +import java.sql.*; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import static br.com.gamemods.minecity.api.StringUtil.identity; + +public class SQLSource implements IDataSource +{ + private static final int VERSION = 7; + + @NotNull + public final MineCity mineCity; + @NotNull + private final SQLConnection connection; + @NotNull + private final SQLCityStorage cityStorage; + @NotNull + private final SQLPermStorage permStorage; + @NotNull + final Map cityMap = new HashMap<>(); + final Map worldDimMap = new ConcurrentHashMap<>(3); + final Set cityNames = new HashSet<>(); + final Map> groupNames = new HashMap<>(); + + public SQLSource(@NotNull MineCity mineCity, @NotNull MineCityConfig config) + { + this.mineCity = mineCity; + connection = new SQLConnection(config.dbUrl, config.dbUser, config.dbPass != null? config.dbPass.clone() : null); + if(config.dbPass != null) + Arrays.fill(config.dbPass, (byte) 0); + + permStorage = new SQLPermStorage(this, connection); + cityStorage = new SQLCityStorage(this, connection, permStorage); + } + + protected WorldDim world(int id, DBSupplier dim, DBSupplier dir, DBSupplier name) + { + WorldDim world = worldDimMap.get(id); + if(world != null) + return world; + + int dimI = dim.get(); + String dirS = dir.get(); + world = mineCity.worldProvider.map(p-> p.getWorld(dimI, dirS)).orElseGet(()-> new WorldDim(dimI, dirS)); + + world.setDataSourceId(id); + worldDimMap.put(id, world); + + if(name != null) + world.name = name.get(); + + return world; + } + + @Slow + private Optional loadCity(Connection connection, int id, @Nullable String identity) throws SQLException, DataSourceException + { + synchronized(cityMap) + { + try(PreparedStatement pst = connection.prepareStatement( + "SELECT `c`.`name`, `owner`, `o`.`player_uuid`, `o`.`player_name`, `spawn_world`, `spawn_x`, `spawn_y`, `spawn_z`, " + + "`w`.`dim`, `w`.`world`, `w`.`name`, `display_name`, c.`perm_denial_message`, `city_id`," + + "`tax_applied_flat`, `tax_applied_percent`, `investment`, `price` " + + "FROM `minecity_city` AS `c` " + + "LEFT JOIN `minecity_players` AS `o` ON `owner` = `o`.`player_id` "+ + "LEFT JOIN `minecity_world` AS `w` ON `spawn_world` = `w`.`world_id` "+ + " WHERE "+(identity == null?"`city_id`=?":"`c`.`name`=?") + )) + { + if(identity == null) + pst.setInt(1, id); + else + pst.setString(1, identity); + + ResultSet result = pst.executeQuery(); + if(!result.next()) + return Optional.empty(); + + PlayerID owner; + int ownerId = result.getInt(2); + if(ownerId <= 0) owner = null; + else + owner = new PlayerID(ownerId, uuid(result.getBytes(3)), result.getString(4)); + + WorldDim world = world(result.getInt(5), ()->result.getInt(9), ()->result.getString(10), ()->result.getString(11)); + BlockPos spawn = new BlockPos(world, result.getInt(6), result.getInt(7), result.getInt(8)); + + String name = result.getString(1); + String displayName = result.getString(12); + + String str = result.getString("perm_denial_message"); + Message message = str == null? null : new Message("", "${msg}", new Object[]{"msg",str}); + id = result.getInt("city_id"); + Tax tax = new Tax(result.getDouble("tax_applied_flat"), result.getDouble("tax_applied_percent")); + if(tax.equals(mineCity.costs.cityTaxApplied)) + tax = mineCity.costs.cityTaxApplied; + double investment = result.getDouble("investment"); + double price = result.getDouble("price"); + pst.close(); + + City city = new City(mineCity, name, displayName, owner, spawn, id, cityStorage, permStorage, message, tax, investment, price); + cityMap.put(id, city); + return Optional.of(city); + } + } + } + + void executeUpdate(PreparedStatement pst, int expected) throws DataSourceException, SQLException + { + int changes = pst.executeUpdate(); + if(changes != expected) + throw new DataSourceException("Expected "+expected+" but got "+changes); + } + + private int insertWorld(Connection connection, WorldDim world) throws SQLException + { + try(PreparedStatement pst = connection.prepareStatement( + "INSERT INTO `minecity_world`(`dim`,`world`,`name`) VALUES(?,?,?)", + Statement.RETURN_GENERATED_KEYS + )) + { + pst.setInt(1, world.dim); + pst.setString(2, world.dir); + setNullableString(pst, 3, world.name); + pst.executeUpdate(); + ResultSet keys = pst.getGeneratedKeys(); + keys.next(); + return keys.getInt(1); + } + } + + @Slow + int worldId(Connection connection, WorldDim world) throws DataSourceException + { + int dataSourceId = world.getDataSourceId(); + if(dataSourceId > 0) return dataSourceId; + + int id = 0; + try + { + try(PreparedStatement pst = connection.prepareStatement( + "SELECT `world_id` FROM `minecity_world` WHERE `dim`=? AND `world`=?" + )) + { + pst.setInt(1, world.dim); + pst.setString(2, world.dir); + ResultSet result = pst.executeQuery(); + if(result.next()) + world.setDataSourceId(id = result.getInt(1)); + } + + if(id <= 0) + insertWorld(connection, world); + + world.setDataSourceId(id); + worldDimMap.putIfAbsent(id, world); + return id; + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Contract("null->null;!null->!null") + byte[] uuid(UUID uuid) + { + if(uuid == null) + return null; + + byte[] bytes = new byte[16]; + ByteBuffer buffer = ByteBuffer.wrap(bytes); + buffer.putLong(uuid.getMostSignificantBits()); + buffer.putLong(uuid.getLeastSignificantBits()); + return bytes; + } + + @Contract("null->null;!null->!null") + UUID uuid(byte[] bytes) throws DataSourceException + { + if(bytes == null) + return null; + + try + { + ByteBuffer bb = ByteBuffer.wrap(bytes); + long firstLong = bb.getLong(); + long secondLong = bb.getLong(); + return new UUID(firstLong, secondLong); + } + catch(Exception e) + { + throw new DataSourceException("Bad UUID", e); + } + } + + void setNullableInt(PreparedStatement pst, int field, int val) throws SQLException + { + if(val == 0) + pst.setNull(field, Types.INTEGER); + else + pst.setInt(field, val); + } + + void setNullableString(PreparedStatement pst, int field, String val) throws SQLException + { + if(val == null) + pst.setNull(field, Types.VARCHAR); + else + pst.setString(field, val); + } + + @Slow + int playerId(Connection connection, @Nullable OptionalPlayer player) throws DataSourceException + { + PlayerID playerId; + if(player == null || (playerId = player.player()) == null) return 0; + int id = player.getDataSourceId(); + if(id > 0) return id; + + try + { + try(PreparedStatement pst = connection.prepareStatement( + "SELECT `player_id` FROM `minecity_players` WHERE `player_uuid`=?" + )) + { + pst.setBytes(1, uuid(playerId.uniqueId)); + ResultSet result = pst.executeQuery(); + if(result.next()) + { + id = result.getInt(1); + playerId.setDataSourceId(id); + return id; + } + } + + try(PreparedStatement pst = connection.prepareStatement( + "INSERT INTO `minecity_players`(`player_uuid`, `player_name`) VALUES(?,?)" + , Statement.RETURN_GENERATED_KEYS + )) + { + pst.setBytes(1, uuid(playerId.uniqueId)); + pst.setString(2, playerId.getName()); + pst.executeUpdate(); + ResultSet keys = pst.getGeneratedKeys(); + keys.next(); + id = keys.getInt(1); + playerId.setDataSourceId(id); + return id; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + int entityId(Connection connection, @Nullable EntityID entity) throws DataSourceException + { + if(entity == null) return 0; + int id = entity.getDataSourceId(); + if(id > 0) return id; + + try + { + try(PreparedStatement pst = connection.prepareStatement( + "SELECT `entity_id` FROM `minecity_entities` WHERE `entity_uuid`=?" + )) + { + pst.setBytes(1, uuid(entity.uniqueId)); + ResultSet result = pst.executeQuery(); + if(result.next()) + { + id = result.getInt(1); + entity.setDataSourceId(id); + return id; + } + } + + try(PreparedStatement pst = connection.prepareStatement( + "INSERT INTO `minecity_entities`(`entity_uuid`, `entity_name`, entity_type) VALUES(?,?,?)" + , Statement.RETURN_GENERATED_KEYS + )) + { + pst.setBytes(1, uuid(entity.uniqueId)); + pst.setString(2, entity.getName()); + pst.setString(3, entity.getEntityType().name()); + pst.executeUpdate(); + ResultSet keys = pst.getGeneratedKeys(); + keys.next(); + id = keys.getInt(1); + entity.setDataSourceId(id); + return id; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + private City city(Connection connection, int cityId) throws SQLException, DataSourceException + { + synchronized(cityMap) + { + City city = cityMap.get(cityId); + if(city != null) + return city; + + return loadCity(connection, cityId, null).orElseThrow(()-> new DataSourceException("City ID "+cityId+" not found")); + } + } + + @Slow + @Nullable + @Override + public ClaimedChunk getCityChunk(@NotNull ChunkPos pos) throws DataSourceException + { + try + { + Connection connection = this.connection.connect(); + try(PreparedStatement pst = connection.prepareStatement( + "SELECT `i`.`city_id`, `i`.`island_id`, reserve FROM `minecity_chunks` AS `c` " + + "INNER JOIN `minecity_world` AS `w` ON `c`.`world_id`=`w`.`world_id` " + + "INNER JOIN `minecity_islands` AS `i` ON `c`.`island_id`=`i`.`island_id` "+ + "WHERE `w`.`dim`=? AND `w`.`world`=? AND `c`.`x`=? AND `c`.`z`=?;" + )) + { + pst.setInt(1, pos.world.dim); + pst.setString(2, pos.world.dir); + pst.setInt(3, pos.x); + pst.setInt(4, pos.z); + ResultSet result = pst.executeQuery(); + if(!result.next()) + return null; + int cityId = result.getInt(1); + int islandId = result.getInt(2); + boolean reserve = result.getBoolean(3); + pst.close(); + + City city = city(connection, cityId); + Island island = city.getIsland(islandId); + return new ClaimedChunk(island != null? island : Inconsistency.getInconsistentIsland(), pos, reserve); + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + catch(UncheckedDataSourceException e) + { + throw e.getCause(); + } + } + + @Slow + int createIsland(Connection transaction, int cityId, WorldDim world) throws DataSourceException, SQLException + { + int worldId = worldId(transaction, world); + int islandId; + try(PreparedStatement pst = transaction.prepareStatement( + "INSERT INTO `minecity_islands`(world_id, city_id) VALUES(?,?)", + Statement.RETURN_GENERATED_KEYS + )) + { + pst.setInt(1, worldId); + pst.setInt(2, cityId); + pst.executeUpdate(); + ResultSet keys = pst.getGeneratedKeys(); + keys.next(); + islandId = keys.getInt(1); + } + + return islandId; + } + + @Slow + void createClaim(Connection connection, int islandId, ChunkPos chunk) throws SQLException, DataSourceException + { + int worldId = worldId(connection, chunk.world); + try(PreparedStatement pst = connection.prepareStatement( + "DELETE FROM minecity_chunks WHERE world_id=? AND x=? AND z=? AND reserve=1" + )) + { + pst.setInt(1, worldId); + pst.setInt(2, chunk.x); + pst.setInt(3, chunk.z); + pst.executeUpdate(); + } + try(PreparedStatement pst = connection.prepareStatement( + "INSERT INTO `minecity_chunks`(world_id, x, z, island_id, reserve) VALUES(?,?,?,?,0)" + )) + { + pst.setInt(1, worldId); + pst.setInt(2, chunk.x); + pst.setInt(3, chunk.z); + pst.setInt(4, islandId); + if(pst.executeUpdate() <= 0) + throw new DataSourceException("Failed to claim the spawn chunk"); + } + } + + @Nullable + @Override + public String checkNameConflict(@NotNull String name) + { + name = identity(name); + for(String cityName : cityNames) + if(identity(cityName).equals(name)) + return cityName; + + return null; + } + + @Slow + @NotNull + @Override + public CityCreationResult createCity(@NotNull City city) throws DataSourceException, IllegalStateException + { + if(city.getId() > 0) + throw new IllegalStateException(); + + try + { + BlockPos spawn = city.getSpawn(); + ChunkPos spawnChunk = spawn.getChunk(); + ClaimedChunk claim = getCityChunk(spawnChunk); + if(claim != null) + throw new IllegalStateException("The chunk " + spawnChunk + " is already claimed: " + claim); + + int islandId; + try(Connection connection = this.connection.transaction()) + { + try + { + int worldId = worldId(connection, spawn.world); + int cityId; + try(PreparedStatement pst = connection.prepareStatement( + "INSERT INTO `minecity_city`(name, owner, spawn_world, spawn_x, spawn_y, spawn_z, display_name, tax_applied_flat, tax_applied_percent, investment) " + + "VALUES ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )", + Statement.RETURN_GENERATED_KEYS + )) + { + pst.setString(1, city.getIdentityName()); + setNullableInt(pst, 2, playerId(connection, city.owner())); + pst.setInt(3, worldId); + pst.setInt(4, spawn.x); + //noinspection SuspiciousNameCombination + pst.setInt(5, spawn.y); + pst.setInt(6, spawn.z); + pst.setString(7, city.getName()); + pst.setDouble(8, city.getAppliedTax().getFlat()); + pst.setDouble(9, city.getAppliedTax().getPercent()); + pst.setDouble(10, city.getInvestment()); + pst.executeUpdate(); + ResultSet keys = pst.getGeneratedKeys(); + keys.next(); + cityId = keys.getInt(1); + city.setId(cityId); + cityMap.put(cityId, city); + } + + islandId = createIsland(connection, cityId, spawnChunk.world); + createClaim(connection, islandId, spawnChunk); + connection.commit(); + cityNames.add(city.getName()); + } + catch(Exception e) + { + connection.rollback(); + throw e; + } + } + + return new CityCreationResult(cityStorage, permStorage, + new SQLIsland(cityStorage, permStorage, islandId, spawnChunk, city), + Collections.emptyList() + ); + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @Override + public void initDB() throws DataSourceException, IOException + { + try(Connection transaction = connection.transaction()) + { + try(Statement stm = transaction.createStatement()) + { + ResultSet result; + int version; + try + { + result = stm.executeQuery("SELECT `value` FROM `minecity_setup` WHERE `property`='version';"); + result.next(); + version = result.getInt(1); + result.close(); + } + catch(SQLException e) + { + System.out.println("[MineCity] Installing the SQL database version "+VERSION); + ScriptRunner runner = new ScriptRunner(transaction, false, true); + runner.setLogWriter(null); + runner.runScript(new InputStreamReader( + getClass().getResourceAsStream("/assets/minecity/db/setup.sql"), "UTF-8" + )); + transaction.commit(); + return; + } + + if(version > VERSION) + throw new DataSourceException("Unsupported database version: "+version); + + if(version < VERSION) + { + System.out.println("[MineCity] Starting the database upgrade from "+version+" to "+VERSION); + for(; version < VERSION; version++) + { + System.out.println("[MineCity] Upgrading to version "+(version+1)); + ScriptRunner runner = new ScriptRunner(transaction, false, true); + runner.setLogWriter(null); + runner.runScript(new InputStreamReader( + getClass().getResourceAsStream("/assets/minecity/db/update_"+version+".sql"), "UTF-8" + )); + } + + transaction.commit(); + System.out.println("[MineCity] The database was successfully upgraded"); + } + + result = stm.executeQuery("SELECT `display_name` FROM `minecity_city` "); + while(result.next()) + cityNames.add(result.getString(1)); + result.close(); + + result = stm.executeQuery("SELECT c.name, g.name FROM minecity_groups g INNER JOIN minecity_city c ON c.city_id = g.city_id"); + while(result.next()) + groupNames.computeIfAbsent(result.getString(1), n-> new HashSet<>(1)).add(result.getString(2)); + } + catch(Exception e) + { + transaction.rollback(); + throw e; + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @NotNull + @Override + public Optional getCityByName(@NotNull String name) throws DataSourceException + { + name = identity(name); + if(name.length() < 3) + return Optional.empty(); + + synchronized(cityMap) + { + for(City city : cityMap.values()) + if(city.getIdentityName().equals(name)) + return Optional.of(city); + + try + { + return loadCity(connection.connect(), 0, name); + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + } + + @NotNull + @Override + public Set getEntityGroups(Identity identity) throws DataSourceException + { + try + { + switch(identity.getType()) + { + case PLAYER: + Connection connection = this.connection.connect(); + try(PreparedStatement pst = connection.prepareStatement( + "SELECT g.group_id, g.city_id, g.display_name, c.display_name AS home " + + "FROM minecity_group_players gp " + + "INNER JOIN minecity_groups g ON g.group_id = gp.group_id " + + "INNER JOIN minecity_city c ON c.city_id = g.city_id " + + "WHERE gp.player_id=?" + )) + { + pst.setInt(1, playerId(connection, (PlayerID) identity)); + ResultSet result = pst.executeQuery(); + Set set = new HashSet<>(2); + while(result.next()) + { + int groupId = result.getInt(1); + int cityId = result.getInt(2); + String name = result.getString(3); + String home = result.getString(4); + GroupID group = Optional.ofNullable(cityMap.get(cityId)) + .map(c-> c.getGroup(groupId)).map(Group::getIdentity) + .orElseGet(()-> new GroupID(groupId, name, home, cityId)) + ; + set.add(group); + } + + return set; + } + + case ENTITY: + connection = this.connection.connect(); + int id = identity.getDataSourceId(); + try(PreparedStatement pst = connection.prepareStatement( + "SELECT g.group_id, g.city_id, g.display_name, c.display_name AS home " + + "FROM minecity_group_entities ge " + + "INNER JOIN minecity_groups g ON g.group_id = ge.group_id " + + "INNER JOIN minecity_city c ON c.city_id = g.city_id " + + (id > 0 ? "WHERE ge.entity_id = ?" : + "INNER JOIN minecity_entities e ON ge.entity_id = e.entity_id " + + "WHERE e.entity_uuid = ?") + )) + { + if(id > 0) + pst.setInt(1, id); + else + pst.setBytes(1, uuid(((EntityID)identity).getUniqueId())); + + ResultSet result = pst.executeQuery(); + Set set = new HashSet<>(2); + while(result.next()) + { + int groupId = result.getInt(1); + int cityId = result.getInt(2); + String name = result.getString(3); + String home = result.getString(4); + GroupID group = Optional.ofNullable(cityMap.get(cityId)) + .map(c-> c.getGroup(groupId)).map(Group::getIdentity) + .orElseGet(()-> new GroupID(groupId, name, home, cityId)) + ; + set.add(group); + } + + return set; + } + + default: + return Collections.emptySet(); + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @NotNull + @Override + public Optional getPlayer(@NotNull String name) throws DataSourceException + { + try(PreparedStatement pst = connection.connect().prepareStatement( + "SELECT player_id, player_uuid, player_name FROM minecity_players WHERE player_name=?" + )) + { + pst.setString(1, name); + ResultSet result = pst.executeQuery(); + if(!result.next()) + return Optional.empty(); + return Optional.of(new PlayerID(result.getInt(1), uuid(result.getBytes(2)), result.getString(3))); + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @NotNull + @Override + public IslandArea getArea(@NotNull Island island) + throws DataSourceException, ClassCastException, IllegalArgumentException + { + SQLIsland sqlIsland = (SQLIsland) island; + + try + { + Connection connection = this.connection.connect(); + try(PreparedStatement pst = connection.prepareStatement( + "SELECT x, z FROM minecity_chunks WHERE island_id=? AND world_id=? AND reserve=0" + )) + { + pst.setInt(1, sqlIsland.id); + pst.setInt(2, worldId(connection, sqlIsland.world)); + ResultSet result = pst.executeQuery(); + List list = new ArrayList<>(); + while(result.next()) + list.add(new ChunkPos(sqlIsland.world, result.getInt(1), result.getInt(2))); + + return new IslandArea(island, list); + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @NotNull + @Override + public Nature getNature(@NotNull WorldDim world) throws DataSourceException + { + try + { + int id = world.getDataSourceId(); + Connection connection = this.connection.connect(); + try(PreparedStatement pst = connection.prepareStatement( + "SELECT world_id, `name`, city_creations, perm_denial_message " + + "FROM minecity_world " + + "WHERE "+(id > 0? "world_id=?":"dim=? AND world=?") + )) + { + if(id > 0) + pst.setInt(1, id); + else + { + pst.setInt(1, world.dim); + pst.setString(2, world.dir); + } + + ResultSet result = pst.executeQuery(); + if(result.next()) + { + if(id == 0) + world.setDataSourceId(result.getInt(1)); + + world.name = result.getString(2); + + boolean cityCreation = result.getBoolean(3); + + String str = result.getString(4); + Message message; + if(str == null) + message = null; + else + message = Message.string(str); + pst.close(); + + return new Nature(mineCity, world, message, permStorage, permStorage, !cityCreation); + } + } + + if(id == 0) + world.setDataSourceId(insertWorld(connection, world)); + + return new Nature(mineCity, world, permStorage, permStorage); + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @NotNull + @Override + public Supplier> cityNameSupplier() + { + return cityNames::stream; + } + + @NotNull + @Override + public Optional> getGroupNames(@NotNull String cityName) + { + Set set = groupNames.get(identity(cityName)); + if(set == null) + return Optional.empty(); + return Optional.of(Collections.unmodifiableSet(set)); + } + + @NotNull + @Override + public Map> getGroups() + { + return Collections.unmodifiableMap(groupNames); + } + + @Override + public int getCityCount(PlayerID playerId) throws DataSourceException + { + try + { + Connection connection = this.connection.connect(); + try(PreparedStatement pst = connection.prepareStatement( + "SELECT count(*) FROM `minecity_city` WHERE `owner`=?" + )) + { + pst.setInt(1, playerId(connection, playerId)); + ResultSet result = pst.executeQuery(); + result.next(); + return result.getInt(1); + } + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } + + @Slow + @Override + public void close() throws DataSourceException + { + try + { + connection.close(); + } + catch(SQLException e) + { + throw new DataSourceException(e); + } + } +} diff --git a/Core/src/main/java/br/com/gamemods/minecity/structure/ChunkOwner.java b/Core/src/main/java/br/com/gamemods/minecity/structure/ChunkOwner.java index d1c04ef8..9c5b1d1c 100644 --- a/Core/src/main/java/br/com/gamemods/minecity/structure/ChunkOwner.java +++ b/Core/src/main/java/br/com/gamemods/minecity/structure/ChunkOwner.java @@ -1,5 +1,5 @@ -package br.com.gamemods.minecity.structure; - -public interface ChunkOwner -{ -} +package br.com.gamemods.minecity.structure; + +public interface ChunkOwner +{ +} diff --git a/Core/src/main/java/br/com/gamemods/minecity/structure/City.java b/Core/src/main/java/br/com/gamemods/minecity/structure/City.java index 8e32d3ad..147a9dc3 100644 --- a/Core/src/main/java/br/com/gamemods/minecity/structure/City.java +++ b/Core/src/main/java/br/com/gamemods/minecity/structure/City.java @@ -1,762 +1,762 @@ -package br.com.gamemods.minecity.structure; - -import br.com.gamemods.minecity.MineCity; -import br.com.gamemods.minecity.api.PlayerID; -import br.com.gamemods.minecity.api.Slow; -import br.com.gamemods.minecity.api.command.LegacyFormat; -import br.com.gamemods.minecity.api.command.Message; -import br.com.gamemods.minecity.api.permission.*; -import br.com.gamemods.minecity.api.world.BlockPos; -import br.com.gamemods.minecity.api.world.ChunkPos; -import br.com.gamemods.minecity.api.world.Direction; -import br.com.gamemods.minecity.api.world.MinecraftEntity; -import br.com.gamemods.minecity.datasource.api.*; -import br.com.gamemods.minecity.datasource.api.unchecked.DBFunction; -import br.com.gamemods.minecity.datasource.api.unchecked.DisDBConsumer; -import br.com.gamemods.minecity.datasource.api.unchecked.UncheckedDataSourceException; -import br.com.gamemods.minecity.economy.Tax; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.AbstractMap.SimpleImmutableEntry; -import java.util.*; -import java.util.Map.Entry; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static br.com.gamemods.minecity.api.StringUtil.identity; - -public final class City extends ExceptStoredHolder -{ - public static final Message INCONSISTENT_CITY_MESSAGE = new Message("inconsistent.city", "This city is inconsistent."); - - @NotNull - public final MineCity mineCity; - - @NotNull - private ICityStorage storage; - - /** - * ID defined by the data source implementation, may be zero but cannot be negative - */ - private int id; - - @NotNull - private String name; - - @NotNull - private String identityName; - - @NotNull - private OptionalPlayer owner; - - @NotNull - private BlockPos spawn; - - @NotNull - private final Map islands; - - @NotNull - private final Map groups; - - private boolean invalid; - - private Message ownerNameCache; - private byte ownerNameLife = Byte.MAX_VALUE; - - @NotNull - private Tax appliedTax; - - private double investment; - - private double price; - - /** - * Create and save a city immediately - * @param owner The city's owner - * @param spawn The city's spawn, the chunk be claimed to this city immediately - * @throws IllegalArgumentException If the spawn's chunk is already reserved or the city's name is invalid - * @throws DataSourceException If a database error occurs - */ - @Slow - public City(@NotNull MineCity mineCity, @NotNull String name, @Nullable PlayerID owner, @NotNull BlockPos spawn, double investment) - throws IllegalArgumentException, DataSourceException - { - this.mineCity = mineCity; - this.investment = investment; - this.name = name; - identityName = identity(name); - appliedTax = mineCity.costs.cityTaxApplied; - this.owner = owner == null? new AdminCity(this) : owner; - this.spawn = spawn; - if(identityName.length() < 3) - throw new IllegalArgumentException("Bad name"); - String conflict = mineCity.dataSource.checkNameConflict(identityName); - if(conflict != null) - throw new IllegalArgumentException("The name is already taken by: "+conflict); - - ClaimedChunk other = mineCity.getChunk(spawn).orElse(null); - if(other != null && !(other.owner instanceof Nature)) - throw new IllegalArgumentException("The chunk "+spawn.getChunk()+" is reserved to "+other.owner); - - CityCreationResult result = mineCity.dataSource.createCity(this); - storage = result.storage; - permissionStorage = result.permissionStorage; - islands = new HashMap<>(1); - islands.put(result.island.getId(), result.island); - groups = new HashMap<>(result.groups.size()); - result.groups.forEach(g -> groups.put(g.getIdentityName(), g)); - - try - { - defaultMessages = mineCity.defaultCityFlags.getDefaultMessages(); - denyAll(mineCity.defaultCityFlags); - } - catch(UncheckedDataSourceException e) - { - System.err.println("[MineCity][SQL] Exception applying the default city flags!"); - e.getCause().printStackTrace(System.err); - } - - try - { - mineCity.reloadChunk(spawn.getChunk()); - } - catch(DataSourceException e) - { - System.err.println("[MineCity][SQL] Exception reloading a chunk"); - e.printStackTrace(System.err); - } - } - - /** - * Constructs an instance of a city that was loaded from the database, do not use this constructor for new cities. - */ - @Slow - public City(@NotNull MineCity mineCity, @NotNull String identityName, @NotNull String name, @Nullable PlayerID owner, - @NotNull BlockPos spawn, int id, @NotNull ICityStorage storage, - @NotNull IExceptPermissionStorage permissionStorage, @Nullable Message defaultDenialMessage, - @NotNull Tax appliedTax, double investment, double price - ) - throws DataSourceException - { - super(defaultDenialMessage); - this.price = price; - this.investment = investment; - this.appliedTax = appliedTax; - this.mineCity = mineCity; - this.name = name; - this.identityName = identityName; - this.owner = owner == null? new AdminCity(this) : owner; - this.spawn = spawn; - setId(id); - this.storage = storage; - this.permissionStorage = permissionStorage; - - Collection loadedIslands = storage.loadIslands(this); - this.islands = new HashMap<>(); - loadedIslands.forEach(i-> islands.put(i.getId(), i)); - - Collection loadedGroups = storage.loadGroups(this); - groups = new HashMap<>(loadedGroups.size()); - loadedGroups.forEach(g -> groups.put(g.getIdentityName(), g)); - - defaultMessages = mineCity.defaultCityFlags.getDefaultMessages(); - loadSimplePermissions(); - loadExceptPermissions(); - } - - @Slow - public synchronized void delete() throws IllegalStateException, DataSourceException - { - if(invalid) - throw new IllegalStateException(); - - try - { - List chunks = islands.values().stream().map( - (DBFunction) Island::getArea).flatMap(IslandArea::claims) - .collect(Collectors.toList()); - - storage.deleteCity(this); - invalid = true; - groups.values().forEach(Group::checkCityValidity); - chunks.forEach(mineCity::reloadChunkSlowly); - } - catch(UncheckedDataSourceException e) - { - throw e.getCause(); - } - } - - @Slow - public synchronized Group createGroup(@NotNull String name) throws IllegalArgumentException, DataSourceException, IllegalStateException - { - if(invalid) - throw new IllegalStateException(); - - String id = identity(name); - Group conflict = groups.get(id); - if(conflict != null) - throw new IllegalArgumentException("The group name '"+name+"' conflicts with '"+conflict.getName()+"'"); - - Group group = storage.createGroup(this, id, name); - groups.put(group.getIdentityName(), group); - return group; - } - - @Slow - public synchronized Group removeGroup(@NotNull String name) throws NoSuchElementException, DataSourceException, IllegalStateException - { - if(invalid) - throw new IllegalStateException(); - - String id = identity(name); - Group group = groups.get(id); - if(group == null) - throw new NoSuchElementException("Group not found: "+name); - - group.remove(); - groups.remove(id); - return group; - } - - public synchronized void removeInvalidGroups() - { - groups.values().removeIf(Group::isInvalid); - } - - - public synchronized void updateGroupName(Group group, String oldName) - throws IllegalStateException, IllegalArgumentException - { - String id = group.getIdentityName(); - if(id.equals(oldName)) - throw new IllegalStateException(); - - if(!groups.remove(oldName, group)) - throw new IllegalArgumentException(); - - groups.put(id, group); - } - - @Nullable - public Group getGroup(int id) - { - if(invalid) - return null; - - for(Group group : groups.values()) - if(group.id == id) - return group; - - return null; - } - - @Nullable - public Group getGroup(@NotNull String name) - { - if(invalid) - return null; - - - return groups.get(identity(name)); - } - - public Collection getGroups() - { - if(invalid) - return Collections.emptyList(); - - return Collections.unmodifiableCollection(groups.values()); - } - - public Set getGroupNames() - { - if(invalid) - return Collections.emptyNavigableSet(); - - return Collections.unmodifiableSet(groups.keySet()); - } - - @NotNull - @Override - public Optional can(@NotNull Identity identity, @NotNull PermissionFlag action) - { - if(invalid) - return Optional.of(mark(INCONSISTENT_CITY_MESSAGE, action)); - - if(identity.equals(owner)) - return Optional.empty(); - - if(identity.getType() == Identity.Type.NATURE) - return Optional.of(mark(new Message("Cities are protected from natural actions"), action)); - - return super.can(identity, action); - } - - @NotNull - @Override - public Optional can(@NotNull MinecraftEntity entity, @NotNull PermissionFlag action) - { - if(invalid) - return Optional.of(mark(INCONSISTENT_CITY_MESSAGE, action)); - - if(entity.getIdentity().equals(owner)) - return Optional.empty(); - - return super.can(entity, action); - } - - @Slow - public void setName(@NotNull String name) throws IllegalArgumentException, DataSourceException, IllegalStateException - { - if(invalid) - throw new IllegalStateException(); - - String identity = identity(name); - if(identity.length() < 3) - throw new IllegalArgumentException("Bad name"); - - if(!identityName.equals(identity)) - { - String conflict = mineCity.dataSource.checkNameConflict(identity); - if(conflict != null) - throw new IllegalArgumentException("The name is already taken by: "+conflict); - } - - storage.setName(this, identity, name); - this.identityName = identity; - this.name = name; - ownerNameCache = null; - groups.values().forEach(Group::updateCityName); - plots().forEach(Plot::updateCityName); - } - - @NotNull - public String getIdentityName() - { - return identityName; - } - - @Nullable - public Island getIsland(int id) - { - if(invalid) - return null; - - return islands.get(id); - } - - @NotNull - public Collection islands() - { - if(invalid) - return Collections.emptyList(); - - return Collections.unmodifiableCollection(islands.values()); - } - - @NotNull - @Override - public OptionalPlayer owner() - { - if(invalid) - return ServerAdmins.INSTANCE; - - return owner; - } - - public int getSizeX() - { - if(invalid) - return 0; - - return islands.values().stream().mapToInt(Island::getSizeX).sum(); - } - - public int getSizeZ() - { - if(invalid) - return 0; - - return islands.values().stream().mapToInt(Island::getSizeZ).sum(); - } - - public int getChunkCount() - { - if(invalid) - return 0; - - return islands.values().stream().mapToInt(Island::getChunkCount).sum(); - } - - @NotNull - public String getName() - { - return name; - } - - @NotNull - public BlockPos getSpawn() - { - return spawn; - } - - @Slow - public Stream connectedIslands(@NotNull ChunkPos chunk) - { - if(invalid) - return Stream.empty(); - - return Direction.cardinal.stream() - .map((DBFunction>) d-> mineCity.getOrFetchChunk(chunk.add(d))) - .filter(Optional::isPresent).map(Optional::get) - .map(ClaimedChunk::getIsland) - .filter(Optional::isPresent).map(Optional::get) - .filter(i-> i.getCity().equals(this)) - ; - } - - @Slow - public Stream> connectedIslandsEntries(@NotNull ChunkPos chunk) - { - if(invalid) - return Stream.empty(); - - return Direction.cardinal.stream() - .map((DBFunction>>) - d-> new SimpleImmutableEntry<>(d, mineCity.getOrFetchChunk(chunk.add(d))) - ) - .filter(e-> !e.getValue().map(c-> c.reserve).orElse(true)) - .map(e-> (Map.Entry) new SimpleImmutableEntry<>(e.getKey(), e.getValue().get().getIsland().orElse(null))) - .filter(e-> e.getValue() != null) - .filter(e-> this.equals(e.getValue().getCity())) - ; - } - - @Slow - public Island claim(@NotNull ChunkPos chunk, boolean createIsland) - throws IllegalArgumentException, DataSourceException, UncheckedDataSourceException, IllegalStateException - { - if(invalid) - throw new IllegalStateException(); - - Optional claimOpt = mineCity.getOrFetchChunk(chunk); - Optional cityOpt = claimOpt.flatMap(ClaimedChunk::getCityAcceptingReserve); - if(cityOpt.isPresent() && (cityOpt.get() != this || !claimOpt.get().reserve)) - throw new IllegalArgumentException("The chunk "+chunk+" is reserved"); - - Set islands = connectedIslands(chunk).collect(Collectors.toSet()); - - if(islands.isEmpty()) - { - if(!createIsland) - throw new IllegalArgumentException("The chunk "+chunk+" is not touching an island owned by city "+identityName); - Island island = storage.createIsland(this, chunk); - this.islands.put(island.getId(), island); - mineCity.reloadChunk(chunk); - reserveChunks(island); - return island; - } - else if(islands.size() == 1) - { - Island island = islands.iterator().next(); - storage.claim(island, chunk); - //long start = System.currentTimeMillis(); - reserveChunks(island); - //long end = System.currentTimeMillis(); - //System.out.println("Reserve chunk took "+(end-start)+"ms"); - return island; - } - else - { - Island mainIsland = storage.claim(islands, chunk); - islands.stream().filter(island -> !island.equals(mainIsland)) - .forEach(island -> this.islands.remove(island.getId())); - reserveChunks(mainIsland); - return mainIsland; - } - } - - @Slow - public Collection disclaim(@NotNull ChunkPos chunk, boolean createIslands) - throws IllegalStateException, IllegalArgumentException, DataSourceException - { - if(invalid) - throw new IllegalStateException(); - - if(islands.size() == 1 && getChunkCount() == 1) - throw new IllegalStateException("Cannot disclaim the last city's chunk, delete the city instead"); - - if(getSpawn().getChunk().equals(chunk)) - throw new IllegalArgumentException("Cannot disclaim the spawn chunk"); - - Optional claim = mineCity.getOrFetchChunk(chunk); - Island island = claim.flatMap(ClaimedChunk::getIsland).filter(i-> i.getCity().equals(this)) - .orElseThrow(()-> new IllegalArgumentException("The chunk " + chunk + " is not owned by the city " + identityName)); - - if(!claim.get().getPlots().isEmpty()) - throw new IllegalArgumentException("Cannot disclaim the chunk "+chunk+" because it contains plots."); - - Map islands = connectedIslandsEntries(chunk).filter(e->e.getValue().equals(island)) - .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); - - if(islands.isEmpty()) - { - storage.deleteIsland(island); - this.islands.remove(island.getId()); - reserveChunks(island); - return Collections.singleton(island); - } - else if(islands.size() == 1) - { - storage.disclaim(chunk, island); - reserveChunks(island); - return Collections.singleton(island); - } - else - { - IslandArea area = mineCity.dataSource.getArea(island); - area.setClaimed(chunk, false); - Set touching = area.touching(chunk); - Set> groups = touching.stream().map(area::contiguous).collect(Collectors.toSet()); - - if(groups.size() == 1) - { - storage.disclaim(chunk, island); - reserveChunks(island); - return Collections.singletonList(island); - } - - if(!createIslands) - throw new IllegalArgumentException("The chunk "+chunk+" is required by other chunks"); - - Collection created = storage.disclaim(chunk, island, groups); - created.forEach(i-> this.islands.put(i.getId(), i)); - groups.forEach(s-> s.forEach((DisDBConsumer) mineCity::reloadChunk)); - Stream.concat(created.stream(), Stream.of(island)).forEach((DisDBConsumer) this::reserveChunks); - return created; - } - } - - public Optional getPlot(String name) - { - return islands().stream().map(i-> i.getPlot(name)).filter(Optional::isPresent).map(Optional::get).findAny(); - } - - public Stream plotNames() - { - return islands().stream().flatMap(Island::getPlotNames); - } - - public Stream plotIdNames() - { - return islands().stream().flatMap(i-> i.getPlotIdNames().stream()); - } - - public Stream plots() - { - return islands().stream().flatMap(i-> i.getPlots().stream()); - } - - public Optional getPlotAt(BlockPos pos) - { - return islands().stream().filter(i-> pos.world.equals(i.world)).map(i-> i.getPlotAt(pos)) - .filter(Optional::isPresent).map(Optional::get).findAny(); - } - - public Stream getPlotsAt(ChunkPos pos) - { - return islands().stream().filter(i-> pos.world.equals(i.world)).flatMap(i-> i.getPlotsAt(pos)); - } - - @Slow - protected void reserveChunks(Island island) throws DataSourceException, IllegalStateException - { - if(invalid) - throw new IllegalStateException(); - - IslandArea area = mineCity.dataSource.getArea(island); - int rangeX = island.getSizeX()/2; - int rangeZ = island.getSizeZ()/2; - - IslandArea reserve; - if(rangeX == 0 && rangeZ == 0) - reserve = area; - else - { - reserve = new IslandArea(island, area.x - rangeX, area.z - rangeZ, - new boolean[area.claims.length + rangeX*2][area.claims[0].length + rangeZ*2] - ); - - area.claims().forEach(p-> { - reserve.claims[p.x-reserve.x][p.z-reserve.z] = true; - for(int rx=-rangeX; rx <= rangeX; rx++) - for(int rz=-rangeZ; rz <= rangeZ; rz++) - reserve.claims[p.x+rx-reserve.x][p.z+rz-reserve.z] = true; - }); - } - - //long start = System.currentTimeMillis(); - Collection update = storage.reserve(reserve); - //long end = System.currentTimeMillis(); - //System.out.println("SQL Call took "+(end-start)+"ms"); - update.forEach(mineCity::reloadChunkSlowly); - } - - @Slow - public void setSpawn(@NotNull BlockPos pos) throws DataSourceException,IllegalArgumentException - { - if(invalid) - throw new IllegalStateException(); - - if(!mineCity.getOrFetchChunk(pos.getChunk()).map(c->c.owner).filter(o->o instanceof Island).map(o->(Island)o) - .filter(i-> i.getCity().equals(this)).isPresent() ) - throw new IllegalArgumentException("The block "+pos+" is not part of the city"); - - storage.setSpawn(this, pos); - this.spawn = pos; - } - - /** - * Changes the owner of the city and saves it immediately - * @param owner The new owner - * @throws DataSourceException If the city is registered and the change failed. The owner will not be set in this case. - */ - @Slow - public void setOwner(@NotNull OptionalPlayer owner) throws DataSourceException, IllegalStateException - { - if(invalid) - throw new IllegalStateException(); - - storage.setOwner(this, owner); - this.owner = owner.getType() == Identity.Type.ADMINS? new AdminCity(this) : owner; - ownerNameCache = null; - plots().forEach(Plot::updateCityName); - } - - /** - * Defines the City ID, this can be done only once and should only be done by the {@link IDataSource} implementation. - * @throws IllegalStateException If the defined ID is different then the passed ID - * @throws IllegalArgumentException If {@code < 0} - */ - public void setId(int id) throws IllegalStateException, IllegalArgumentException - { - if(id < 0 && identityName.charAt(0) != '#') - throw new IllegalArgumentException("id = "+id); - if(this.id > 0 && id != this.id) - throw new IllegalStateException("Tried to change the city's \""+identityName+"\" ID from "+this.id+" to "+id); - - this.id = id; - } - - /** - * @return The City ID - */ - public int getId() - { - return id; - } - - @Override - public boolean equals(Object o) - { - if(this == o) return true; - if(o == null || getClass() != o.getClass()) return false; - - City city = (City) o; - return id == city.id && identityName.equals(city.identityName); - } - - @Override - public int hashCode() - { - int result = id; - result = 31*result + identityName.hashCode(); - return result; - } - - public LegacyFormat getColor() - { - if(name.charAt(0) == '#') - return LegacyFormat.DARK_RED; - - if(owner.getType() == Identity.Type.ADMINS) - return LegacyFormat.RED; - - return LegacyFormat.CITY_COLORS[id%LegacyFormat.CITY_COLORS.length]; - } - - public boolean isInvalid() - { - return invalid; - } - - @Override - public String toString() - { - return "City{" + - "id=" + id + - ", identityName='" + identityName + '\'' + - "}"; - } - - @Override - public Message ownerName() - { - Message cache = this.ownerNameCache; - if(cache != null && --ownerNameLife > 0) - return this.ownerNameCache; - - ownerNameLife = 127; - Message msg; - if(owner.getType() == Identity.Type.ADMINS) - { - msg = new Message("action.denied.city.admin", "${name}", new Object[]{"name", name}); - } - else - { - msg = new Message("action.denied.city.normal", "${name} ~ ${owner}", new Object[][]{ - {"name", name}, {"owner", owner.getName()} - }); - } - - return this.ownerNameCache = msg; - } - - @NotNull - public Tax getAppliedTax() - { - return appliedTax; - } - - public double getInvestment() - { - return investment; - } - - @Slow - public synchronized void invested(double value) throws DataSourceException - { - if(invalid) - throw new IllegalStateException("This instance is no longer valid"); - - investment = storage.invested(this, value); - } - - public double getPrice() - { - return price; - } - - @Slow - public void setPrice(double price) throws DataSourceException - { - if(invalid) - throw new IllegalStateException("This instance is no longer valid"); - - storage.setPrice(this, price); - this.price = price; - } -} +package br.com.gamemods.minecity.structure; + +import br.com.gamemods.minecity.MineCity; +import br.com.gamemods.minecity.api.PlayerID; +import br.com.gamemods.minecity.api.Slow; +import br.com.gamemods.minecity.api.command.LegacyFormat; +import br.com.gamemods.minecity.api.command.Message; +import br.com.gamemods.minecity.api.permission.*; +import br.com.gamemods.minecity.api.world.BlockPos; +import br.com.gamemods.minecity.api.world.ChunkPos; +import br.com.gamemods.minecity.api.world.Direction; +import br.com.gamemods.minecity.api.world.MinecraftEntity; +import br.com.gamemods.minecity.datasource.api.*; +import br.com.gamemods.minecity.datasource.api.unchecked.DBFunction; +import br.com.gamemods.minecity.datasource.api.unchecked.DisDBConsumer; +import br.com.gamemods.minecity.datasource.api.unchecked.UncheckedDataSourceException; +import br.com.gamemods.minecity.economy.Tax; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.AbstractMap.SimpleImmutableEntry; +import java.util.*; +import java.util.Map.Entry; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static br.com.gamemods.minecity.api.StringUtil.identity; + +public final class City extends ExceptStoredHolder +{ + public static final Message INCONSISTENT_CITY_MESSAGE = new Message("inconsistent.city", "This city is inconsistent."); + + @NotNull + public final MineCity mineCity; + + @NotNull + private ICityStorage storage; + + /** + * ID defined by the data source implementation, may be zero but cannot be negative + */ + private int id; + + @NotNull + private String name; + + @NotNull + private String identityName; + + @NotNull + private OptionalPlayer owner; + + @NotNull + private BlockPos spawn; + + @NotNull + private final Map islands; + + @NotNull + private final Map groups; + + private boolean invalid; + + private Message ownerNameCache; + private byte ownerNameLife = Byte.MAX_VALUE; + + @NotNull + private Tax appliedTax; + + private double investment; + + private double price; + + /** + * Create and save a city immediately + * @param owner The city's owner + * @param spawn The city's spawn, the chunk be claimed to this city immediately + * @throws IllegalArgumentException If the spawn's chunk is already reserved or the city's name is invalid + * @throws DataSourceException If a database error occurs + */ + @Slow + public City(@NotNull MineCity mineCity, @NotNull String name, @Nullable PlayerID owner, @NotNull BlockPos spawn, double investment) + throws IllegalArgumentException, DataSourceException + { + this.mineCity = mineCity; + this.investment = investment; + this.name = name; + identityName = identity(name); + appliedTax = mineCity.costs.cityTaxApplied; + this.owner = owner == null? new AdminCity(this) : owner; + this.spawn = spawn; + if(identityName.length() < 3) + throw new IllegalArgumentException("Bad name"); + String conflict = mineCity.dataSource.checkNameConflict(identityName); + if(conflict != null) + throw new IllegalArgumentException("The name is already taken by: "+conflict); + + ClaimedChunk other = mineCity.getChunk(spawn).orElse(null); + if(other != null && !(other.owner instanceof Nature)) + throw new IllegalArgumentException("The chunk "+spawn.getChunk()+" is reserved to "+other.owner); + + CityCreationResult result = mineCity.dataSource.createCity(this); + storage = result.storage; + permissionStorage = result.permissionStorage; + islands = new HashMap<>(1); + islands.put(result.island.getId(), result.island); + groups = new HashMap<>(result.groups.size()); + result.groups.forEach(g -> groups.put(g.getIdentityName(), g)); + + try + { + defaultMessages = mineCity.defaultCityFlags.getDefaultMessages(); + denyAll(mineCity.defaultCityFlags); + } + catch(UncheckedDataSourceException e) + { + System.err.println("[MineCity][SQL] Exception applying the default city flags!"); + e.getCause().printStackTrace(System.err); + } + + try + { + mineCity.reloadChunk(spawn.getChunk()); + } + catch(DataSourceException e) + { + System.err.println("[MineCity][SQL] Exception reloading a chunk"); + e.printStackTrace(System.err); + } + } + + /** + * Constructs an instance of a city that was loaded from the database, do not use this constructor for new cities. + */ + @Slow + public City(@NotNull MineCity mineCity, @NotNull String identityName, @NotNull String name, @Nullable PlayerID owner, + @NotNull BlockPos spawn, int id, @NotNull ICityStorage storage, + @NotNull IExceptPermissionStorage permissionStorage, @Nullable Message defaultDenialMessage, + @NotNull Tax appliedTax, double investment, double price + ) + throws DataSourceException + { + super(defaultDenialMessage); + this.price = price; + this.investment = investment; + this.appliedTax = appliedTax; + this.mineCity = mineCity; + this.name = name; + this.identityName = identityName; + this.owner = owner == null? new AdminCity(this) : owner; + this.spawn = spawn; + setId(id); + this.storage = storage; + this.permissionStorage = permissionStorage; + + Collection loadedIslands = storage.loadIslands(this); + this.islands = new HashMap<>(); + loadedIslands.forEach(i-> islands.put(i.getId(), i)); + + Collection loadedGroups = storage.loadGroups(this); + groups = new HashMap<>(loadedGroups.size()); + loadedGroups.forEach(g -> groups.put(g.getIdentityName(), g)); + + defaultMessages = mineCity.defaultCityFlags.getDefaultMessages(); + loadSimplePermissions(); + loadExceptPermissions(); + } + + @Slow + public synchronized void delete() throws IllegalStateException, DataSourceException + { + if(invalid) + throw new IllegalStateException(); + + try + { + List chunks = islands.values().stream().map( + (DBFunction) Island::getArea).flatMap(IslandArea::claims) + .collect(Collectors.toList()); + + storage.deleteCity(this); + invalid = true; + groups.values().forEach(Group::checkCityValidity); + chunks.forEach(mineCity::reloadChunkSlowly); + } + catch(UncheckedDataSourceException e) + { + throw e.getCause(); + } + } + + @Slow + public synchronized Group createGroup(@NotNull String name) throws IllegalArgumentException, DataSourceException, IllegalStateException + { + if(invalid) + throw new IllegalStateException(); + + String id = identity(name); + Group conflict = groups.get(id); + if(conflict != null) + throw new IllegalArgumentException("The group name '"+name+"' conflicts with '"+conflict.getName()+"'"); + + Group group = storage.createGroup(this, id, name); + groups.put(group.getIdentityName(), group); + return group; + } + + @Slow + public synchronized Group removeGroup(@NotNull String name) throws NoSuchElementException, DataSourceException, IllegalStateException + { + if(invalid) + throw new IllegalStateException(); + + String id = identity(name); + Group group = groups.get(id); + if(group == null) + throw new NoSuchElementException("Group not found: "+name); + + group.remove(); + groups.remove(id); + return group; + } + + public synchronized void removeInvalidGroups() + { + groups.values().removeIf(Group::isInvalid); + } + + + public synchronized void updateGroupName(Group group, String oldName) + throws IllegalStateException, IllegalArgumentException + { + String id = group.getIdentityName(); + if(id.equals(oldName)) + throw new IllegalStateException(); + + if(!groups.remove(oldName, group)) + throw new IllegalArgumentException(); + + groups.put(id, group); + } + + @Nullable + public Group getGroup(int id) + { + if(invalid) + return null; + + for(Group group : groups.values()) + if(group.id == id) + return group; + + return null; + } + + @Nullable + public Group getGroup(@NotNull String name) + { + if(invalid) + return null; + + + return groups.get(identity(name)); + } + + public Collection getGroups() + { + if(invalid) + return Collections.emptyList(); + + return Collections.unmodifiableCollection(groups.values()); + } + + public Set getGroupNames() + { + if(invalid) + return Collections.emptyNavigableSet(); + + return Collections.unmodifiableSet(groups.keySet()); + } + + @NotNull + @Override + public Optional can(@NotNull Identity identity, @NotNull PermissionFlag action) + { + if(invalid) + return Optional.of(mark(INCONSISTENT_CITY_MESSAGE, action)); + + if(identity.equals(owner)) + return Optional.empty(); + + if(identity.getType() == Identity.Type.NATURE) + return Optional.of(mark(new Message("Cities are protected from natural actions"), action)); + + return super.can(identity, action); + } + + @NotNull + @Override + public Optional can(@NotNull MinecraftEntity entity, @NotNull PermissionFlag action) + { + if(invalid) + return Optional.of(mark(INCONSISTENT_CITY_MESSAGE, action)); + + if(entity.getIdentity().equals(owner)) + return Optional.empty(); + + return super.can(entity, action); + } + + @Slow + public void setName(@NotNull String name) throws IllegalArgumentException, DataSourceException, IllegalStateException + { + if(invalid) + throw new IllegalStateException(); + + String identity = identity(name); + if(identity.length() < 3) + throw new IllegalArgumentException("Bad name"); + + if(!identityName.equals(identity)) + { + String conflict = mineCity.dataSource.checkNameConflict(identity); + if(conflict != null) + throw new IllegalArgumentException("The name is already taken by: "+conflict); + } + + storage.setName(this, identity, name); + this.identityName = identity; + this.name = name; + ownerNameCache = null; + groups.values().forEach(Group::updateCityName); + plots().forEach(Plot::updateCityName); + } + + @NotNull + public String getIdentityName() + { + return identityName; + } + + @Nullable + public Island getIsland(int id) + { + if(invalid) + return null; + + return islands.get(id); + } + + @NotNull + public Collection islands() + { + if(invalid) + return Collections.emptyList(); + + return Collections.unmodifiableCollection(islands.values()); + } + + @NotNull + @Override + public OptionalPlayer owner() + { + if(invalid) + return ServerAdmins.INSTANCE; + + return owner; + } + + public int getSizeX() + { + if(invalid) + return 0; + + return islands.values().stream().mapToInt(Island::getSizeX).sum(); + } + + public int getSizeZ() + { + if(invalid) + return 0; + + return islands.values().stream().mapToInt(Island::getSizeZ).sum(); + } + + public int getChunkCount() + { + if(invalid) + return 0; + + return islands.values().stream().mapToInt(Island::getChunkCount).sum(); + } + + @NotNull + public String getName() + { + return name; + } + + @NotNull + public BlockPos getSpawn() + { + return spawn; + } + + @Slow + public Stream connectedIslands(@NotNull ChunkPos chunk) + { + if(invalid) + return Stream.empty(); + + return Direction.cardinal.stream() + .map((DBFunction>) d-> mineCity.getOrFetchChunk(chunk.add(d))) + .filter(Optional::isPresent).map(Optional::get) + .map(ClaimedChunk::getIsland) + .filter(Optional::isPresent).map(Optional::get) + .filter(i-> i.getCity().equals(this)) + ; + } + + @Slow + public Stream> connectedIslandsEntries(@NotNull ChunkPos chunk) + { + if(invalid) + return Stream.empty(); + + return Direction.cardinal.stream() + .map((DBFunction>>) + d-> new SimpleImmutableEntry<>(d, mineCity.getOrFetchChunk(chunk.add(d))) + ) + .filter(e-> !e.getValue().map(c-> c.reserve).orElse(true)) + .map(e-> (Map.Entry) new SimpleImmutableEntry<>(e.getKey(), e.getValue().get().getIsland().orElse(null))) + .filter(e-> e.getValue() != null) + .filter(e-> this.equals(e.getValue().getCity())) + ; + } + + @Slow + public Island claim(@NotNull ChunkPos chunk, boolean createIsland) + throws IllegalArgumentException, DataSourceException, UncheckedDataSourceException, IllegalStateException + { + if(invalid) + throw new IllegalStateException(); + + Optional claimOpt = mineCity.getOrFetchChunk(chunk); + Optional cityOpt = claimOpt.flatMap(ClaimedChunk::getCityAcceptingReserve); + if(cityOpt.isPresent() && (cityOpt.get() != this || !claimOpt.get().reserve)) + throw new IllegalArgumentException("The chunk "+chunk+" is reserved"); + + Set islands = connectedIslands(chunk).collect(Collectors.toSet()); + + if(islands.isEmpty()) + { + if(!createIsland) + throw new IllegalArgumentException("The chunk "+chunk+" is not touching an island owned by city "+identityName); + Island island = storage.createIsland(this, chunk); + this.islands.put(island.getId(), island); + mineCity.reloadChunk(chunk); + reserveChunks(island); + return island; + } + else if(islands.size() == 1) + { + Island island = islands.iterator().next(); + storage.claim(island, chunk); + //long start = System.currentTimeMillis(); + reserveChunks(island); + //long end = System.currentTimeMillis(); + //System.out.println("Reserve chunk took "+(end-start)+"ms"); + return island; + } + else + { + Island mainIsland = storage.claim(islands, chunk); + islands.stream().filter(island -> !island.equals(mainIsland)) + .forEach(island -> this.islands.remove(island.getId())); + reserveChunks(mainIsland); + return mainIsland; + } + } + + @Slow + public Collection disclaim(@NotNull ChunkPos chunk, boolean createIslands) + throws IllegalStateException, IllegalArgumentException, DataSourceException + { + if(invalid) + throw new IllegalStateException(); + + if(islands.size() == 1 && getChunkCount() == 1) + throw new IllegalStateException("Cannot disclaim the last city's chunk, delete the city instead"); + + if(getSpawn().getChunk().equals(chunk)) + throw new IllegalArgumentException("Cannot disclaim the spawn chunk"); + + Optional claim = mineCity.getOrFetchChunk(chunk); + Island island = claim.flatMap(ClaimedChunk::getIsland).filter(i-> i.getCity().equals(this)) + .orElseThrow(()-> new IllegalArgumentException("The chunk " + chunk + " is not owned by the city " + identityName)); + + if(!claim.get().getPlots().isEmpty()) + throw new IllegalArgumentException("Cannot disclaim the chunk "+chunk+" because it contains plots."); + + Map islands = connectedIslandsEntries(chunk).filter(e->e.getValue().equals(island)) + .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); + + if(islands.isEmpty()) + { + storage.deleteIsland(island); + this.islands.remove(island.getId()); + reserveChunks(island); + return Collections.singleton(island); + } + else if(islands.size() == 1) + { + storage.disclaim(chunk, island); + reserveChunks(island); + return Collections.singleton(island); + } + else + { + IslandArea area = mineCity.dataSource.getArea(island); + area.setClaimed(chunk, false); + Set touching = area.touching(chunk); + Set> groups = touching.stream().map(area::contiguous).collect(Collectors.toSet()); + + if(groups.size() == 1) + { + storage.disclaim(chunk, island); + reserveChunks(island); + return Collections.singletonList(island); + } + + if(!createIslands) + throw new IllegalArgumentException("The chunk "+chunk+" is required by other chunks"); + + Collection created = storage.disclaim(chunk, island, groups); + created.forEach(i-> this.islands.put(i.getId(), i)); + groups.forEach(s-> s.forEach((DisDBConsumer) mineCity::reloadChunk)); + Stream.concat(created.stream(), Stream.of(island)).forEach((DisDBConsumer) this::reserveChunks); + return created; + } + } + + public Optional getPlot(String name) + { + return islands().stream().map(i-> i.getPlot(name)).filter(Optional::isPresent).map(Optional::get).findAny(); + } + + public Stream plotNames() + { + return islands().stream().flatMap(Island::getPlotNames); + } + + public Stream plotIdNames() + { + return islands().stream().flatMap(i-> i.getPlotIdNames().stream()); + } + + public Stream plots() + { + return islands().stream().flatMap(i-> i.getPlots().stream()); + } + + public Optional getPlotAt(BlockPos pos) + { + return islands().stream().filter(i-> pos.world.equals(i.world)).map(i-> i.getPlotAt(pos)) + .filter(Optional::isPresent).map(Optional::get).findAny(); + } + + public Stream getPlotsAt(ChunkPos pos) + { + return islands().stream().filter(i-> pos.world.equals(i.world)).flatMap(i-> i.getPlotsAt(pos)); + } + + @Slow + protected void reserveChunks(Island island) throws DataSourceException, IllegalStateException + { + if(invalid) + throw new IllegalStateException(); + + IslandArea area = mineCity.dataSource.getArea(island); + int rangeX = island.getSizeX()/2; + int rangeZ = island.getSizeZ()/2; + + IslandArea reserve; + if(rangeX == 0 && rangeZ == 0) + reserve = area; + else + { + reserve = new IslandArea(island, area.x - rangeX, area.z - rangeZ, + new boolean[area.claims.length + rangeX*2][area.claims[0].length + rangeZ*2] + ); + + area.claims().forEach(p-> { + reserve.claims[p.x-reserve.x][p.z-reserve.z] = true; + for(int rx=-rangeX; rx <= rangeX; rx++) + for(int rz=-rangeZ; rz <= rangeZ; rz++) + reserve.claims[p.x+rx-reserve.x][p.z+rz-reserve.z] = true; + }); + } + + //long start = System.currentTimeMillis(); + Collection update = storage.reserve(reserve); + //long end = System.currentTimeMillis(); + //System.out.println("SQL Call took "+(end-start)+"ms"); + update.forEach(mineCity::reloadChunkSlowly); + } + + @Slow + public void setSpawn(@NotNull BlockPos pos) throws DataSourceException,IllegalArgumentException + { + if(invalid) + throw new IllegalStateException(); + + if(!mineCity.getOrFetchChunk(pos.getChunk()).map(c->c.owner).filter(o->o instanceof Island).map(o->(Island)o) + .filter(i-> i.getCity().equals(this)).isPresent() ) + throw new IllegalArgumentException("The block "+pos+" is not part of the city"); + + storage.setSpawn(this, pos); + this.spawn = pos; + } + + /** + * Changes the owner of the city and saves it immediately + * @param owner The new owner + * @throws DataSourceException If the city is registered and the change failed. The owner will not be set in this case. + */ + @Slow + public void setOwner(@NotNull OptionalPlayer owner) throws DataSourceException, IllegalStateException + { + if(invalid) + throw new IllegalStateException(); + + storage.setOwner(this, owner); + this.owner = owner.getType() == Identity.Type.ADMINS? new AdminCity(this) : owner; + ownerNameCache = null; + plots().forEach(Plot::updateCityName); + } + + /** + * Defines the City ID, this can be done only once and should only be done by the {@link IDataSource} implementation. + * @throws IllegalStateException If the defined ID is different then the passed ID + * @throws IllegalArgumentException If {@code < 0} + */ + public void setId(int id) throws IllegalStateException, IllegalArgumentException + { + if(id < 0 && identityName.charAt(0) != '#') + throw new IllegalArgumentException("id = "+id); + if(this.id > 0 && id != this.id) + throw new IllegalStateException("Tried to change the city's \""+identityName+"\" ID from "+this.id+" to "+id); + + this.id = id; + } + + /** + * @return The City ID + */ + public int getId() + { + return id; + } + + @Override + public boolean equals(Object o) + { + if(this == o) return true; + if(o == null || getClass() != o.getClass()) return false; + + City city = (City) o; + return id == city.id && identityName.equals(city.identityName); + } + + @Override + public int hashCode() + { + int result = id; + result = 31*result + identityName.hashCode(); + return result; + } + + public LegacyFormat getColor() + { + if(name.charAt(0) == '#') + return LegacyFormat.DARK_RED; + + if(owner.getType() == Identity.Type.ADMINS) + return LegacyFormat.RED; + + return LegacyFormat.CITY_COLORS[id%LegacyFormat.CITY_COLORS.length]; + } + + public boolean isInvalid() + { + return invalid; + } + + @Override + public String toString() + { + return "City{" + + "id=" + id + + ", identityName='" + identityName + '\'' + + "}"; + } + + @Override + public Message ownerName() + { + Message cache = this.ownerNameCache; + if(cache != null && --ownerNameLife > 0) + return this.ownerNameCache; + + ownerNameLife = 127; + Message msg; + if(owner.getType() == Identity.Type.ADMINS) + { + msg = new Message("action.denied.city.admin", "${name}", new Object[]{"name", name}); + } + else + { + msg = new Message("action.denied.city.normal", "${name} ~ ${owner}", new Object[][]{ + {"name", name}, {"owner", owner.getName()} + }); + } + + return this.ownerNameCache = msg; + } + + @NotNull + public Tax getAppliedTax() + { + return appliedTax; + } + + public double getInvestment() + { + return investment; + } + + @Slow + public synchronized void invested(double value) throws DataSourceException + { + if(invalid) + throw new IllegalStateException("This instance is no longer valid"); + + investment = storage.invested(this, value); + } + + public double getPrice() + { + return price; + } + + @Slow + public void setPrice(double price) throws DataSourceException + { + if(invalid) + throw new IllegalStateException("This instance is no longer valid"); + + storage.setPrice(this, price); + this.price = price; + } +} diff --git a/Core/src/main/java/br/com/gamemods/minecity/structure/ClaimedChunk.java b/Core/src/main/java/br/com/gamemods/minecity/structure/ClaimedChunk.java index 339560b6..082d76d3 100644 --- a/Core/src/main/java/br/com/gamemods/minecity/structure/ClaimedChunk.java +++ b/Core/src/main/java/br/com/gamemods/minecity/structure/ClaimedChunk.java @@ -1,195 +1,195 @@ -package br.com.gamemods.minecity.structure; - -import br.com.gamemods.minecity.api.permission.FlagHolder; -import br.com.gamemods.minecity.api.world.BlockPos; -import br.com.gamemods.minecity.api.world.ChunkPos; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public final class ClaimedChunk -{ - @NotNull - public final ChunkOwner owner; - @NotNull - public final ChunkPos chunk; - public final boolean reserve; - @Nullable - private Set plots; - private boolean invalid; - - public ClaimedChunk(@NotNull ChunkOwner owner, @NotNull ChunkPos chunk) - { - this.owner = owner; - this.chunk = chunk; - this.reserve = owner instanceof Reserve; - } - - public ClaimedChunk(@NotNull Island owner, @NotNull ChunkPos chunk, boolean reserve) - { - this.owner = reserve? owner.reserve : owner; - this.chunk = chunk; - this.reserve = reserve; - } - - public Optional getPlotAt(BlockPos pos) - { - if(!pos.world.equals(chunk.world)) - return Optional.empty(); - - return getPlotAt(pos.x, pos.y, pos.z); - } - - public Optional getPlotAt(int x, int y, int z) - { - for(Plot plot : getPlots()) - if(plot.getShape().contains(x, y, z)) - return Optional.of(plot); - - return Optional.empty(); - } - - public Collection getPlots() - { - if(plots != null) - return plots; - - if(reserve) - return plots = Collections.emptySet(); - - return plots = getIsland().map(i -> i.getPlotsAt(chunk)).orElse(Stream.empty()).collect(Collectors.toSet()); - } - - public Optional getIslandAcceptingReserve() - { - if(!reserve) - return getIsland(); - - return Optional.of(((Reserve)owner).island); - } - - @NotNull - public Optional getIsland() - { - if(owner instanceof Island) return Optional.of((Island) owner); - if(owner instanceof Inconsistency) return Optional.of(Inconsistency.getInconsistentIsland()); - return Optional.empty(); - } - - public Optional getReserve() - { - if(owner instanceof Reserve) return Optional.of((Reserve)owner); - return Optional.empty(); - } - - public Optional nature() - { - Nature nature = chunk.world.nature; - if(nature != null) - return Optional.of(nature); - - if(owner instanceof Nature) - return Optional.of((Nature) owner); - - return Optional.empty(); - } - - /** - * @throws NoSuchElementException If the chunk is reserved but the nature object is not available - */ - @NotNull - public FlagHolder getFlagHolder() - { - if(reserve) - return (Reserve) owner; - - return getIsland().map(Island::getCity).orElse(chunk.world.nature); - } - - /** - * @throws NoSuchElementException If the chunk is reserved but the nature object is not available - */ - @NotNull - public FlagHolder getFlagHolder(int blockX, int blockY, int blockZ) - { - if(reserve) - return (Reserve) owner; - - Optional plot = getPlotAt(blockX, blockY, blockZ); - if(plot.isPresent()) - return plot.get(); - - return getIsland().map(Island::getCity).orElse(chunk.world.nature); - } - - public FlagHolder getFlagHolder(BlockPos pos) - { - return getFlagHolder(pos.x, pos.y, pos.z); - } - - @NotNull - public Optional getCity() - { - return getIsland().map(Island::getCity); - } - - public Optional getCityAcceptingReserve() - { - if(!reserve) - return getCity(); - - return Optional.of(((Reserve)owner).island.getCity()); - } - - @NotNull - public ChunkOwner getOwner() - { - return owner; - } - - @NotNull - public ChunkPos getChunk() - { - return chunk; - } - - public boolean isInvalid() - { - return invalid; - } - - public void invalidate() - { - invalid = true; - } - - @Override - public String toString() - { - return "CityChunk{" + - "owner=" + owner + - ", chunk=" + chunk + - '}'; - } - - @Override - public boolean equals(Object o) - { - if(this == o) return true; - if(o == null || getClass() != o.getClass()) return false; - - ClaimedChunk that = (ClaimedChunk) o; - return owner.equals(that.owner) && chunk.equals(that.chunk); - } - - @Override - public int hashCode() - { - int result = owner.hashCode(); - result = 31*result + chunk.hashCode(); - return result; - } -} +package br.com.gamemods.minecity.structure; + +import br.com.gamemods.minecity.api.permission.FlagHolder; +import br.com.gamemods.minecity.api.world.BlockPos; +import br.com.gamemods.minecity.api.world.ChunkPos; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public final class ClaimedChunk +{ + @NotNull + public final ChunkOwner owner; + @NotNull + public final ChunkPos chunk; + public final boolean reserve; + @Nullable + private Set plots; + private boolean invalid; + + public ClaimedChunk(@NotNull ChunkOwner owner, @NotNull ChunkPos chunk) + { + this.owner = owner; + this.chunk = chunk; + this.reserve = owner instanceof Reserve; + } + + public ClaimedChunk(@NotNull Island owner, @NotNull ChunkPos chunk, boolean reserve) + { + this.owner = reserve? owner.reserve : owner; + this.chunk = chunk; + this.reserve = reserve; + } + + public Optional getPlotAt(BlockPos pos) + { + if(!pos.world.equals(chunk.world)) + return Optional.empty(); + + return getPlotAt(pos.x, pos.y, pos.z); + } + + public Optional getPlotAt(int x, int y, int z) + { + for(Plot plot : getPlots()) + if(plot.getShape().contains(x, y, z)) + return Optional.of(plot); + + return Optional.empty(); + } + + public Collection getPlots() + { + if(plots != null) + return plots; + + if(reserve) + return plots = Collections.emptySet(); + + return plots = getIsland().map(i -> i.getPlotsAt(chunk)).orElse(Stream.empty()).collect(Collectors.toSet()); + } + + public Optional getIslandAcceptingReserve() + { + if(!reserve) + return getIsland(); + + return Optional.of(((Reserve)owner).island); + } + + @NotNull + public Optional getIsland() + { + if(owner instanceof Island) return Optional.of((Island) owner); + if(owner instanceof Inconsistency) return Optional.of(Inconsistency.getInconsistentIsland()); + return Optional.empty(); + } + + public Optional getReserve() + { + if(owner instanceof Reserve) return Optional.of((Reserve)owner); + return Optional.empty(); + } + + public Optional nature() + { + Nature nature = chunk.world.nature; + if(nature != null) + return Optional.of(nature); + + if(owner instanceof Nature) + return Optional.of((Nature) owner); + + return Optional.empty(); + } + + /** + * @throws NoSuchElementException If the chunk is reserved but the nature object is not available + */ + @NotNull + public FlagHolder getFlagHolder() + { + if(reserve) + return (Reserve) owner; + + return getIsland().map(Island::getCity).orElse(chunk.world.nature); + } + + /** + * @throws NoSuchElementException If the chunk is reserved but the nature object is not available + */ + @NotNull + public FlagHolder getFlagHolder(int blockX, int blockY, int blockZ) + { + if(reserve) + return (Reserve) owner; + + Optional plot = getPlotAt(blockX, blockY, blockZ); + if(plot.isPresent()) + return plot.get(); + + return getIsland().map(Island::getCity).orElse(chunk.world.nature); + } + + public FlagHolder getFlagHolder(BlockPos pos) + { + return getFlagHolder(pos.x, pos.y, pos.z); + } + + @NotNull + public Optional getCity() + { + return getIsland().map(Island::getCity); + } + + public Optional getCityAcceptingReserve() + { + if(!reserve) + return getCity(); + + return Optional.of(((Reserve)owner).island.getCity()); + } + + @NotNull + public ChunkOwner getOwner() + { + return owner; + } + + @NotNull + public ChunkPos getChunk() + { + return chunk; + } + + public boolean isInvalid() + { + return invalid; + } + + public void invalidate() + { + invalid = true; + } + + @Override + public String toString() + { + return "CityChunk{" + + "owner=" + owner + + ", chunk=" + chunk + + '}'; + } + + @Override + public boolean equals(Object o) + { + if(this == o) return true; + if(o == null || getClass() != o.getClass()) return false; + + ClaimedChunk that = (ClaimedChunk) o; + return owner.equals(that.owner) && chunk.equals(that.chunk); + } + + @Override + public int hashCode() + { + int result = owner.hashCode(); + result = 31*result + chunk.hashCode(); + return result; + } +} diff --git a/Core/src/main/java/br/com/gamemods/minecity/structure/Inconsistency.java b/Core/src/main/java/br/com/gamemods/minecity/structure/Inconsistency.java index d3d57cd9..f87320bd 100644 --- a/Core/src/main/java/br/com/gamemods/minecity/structure/Inconsistency.java +++ b/Core/src/main/java/br/com/gamemods/minecity/structure/Inconsistency.java @@ -1,457 +1,457 @@ -package br.com.gamemods.minecity.structure; - -import br.com.gamemods.minecity.MineCity; -import br.com.gamemods.minecity.api.PlayerID; -import br.com.gamemods.minecity.api.command.Message; -import br.com.gamemods.minecity.api.permission.*; -import br.com.gamemods.minecity.api.shape.Shape; -import br.com.gamemods.minecity.api.world.BlockPos; -import br.com.gamemods.minecity.api.world.ChunkPos; -import br.com.gamemods.minecity.api.world.WorldDim; -import br.com.gamemods.minecity.datasource.api.DataSourceException; -import br.com.gamemods.minecity.datasource.api.ICityStorage; -import br.com.gamemods.minecity.datasource.api.IExceptPermissionStorage; -import br.com.gamemods.minecity.datasource.api.INatureStorage; -import br.com.gamemods.minecity.datasource.api.unchecked.UncheckedDataSourceException; -import br.com.gamemods.minecity.economy.Tax; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.*; - -public class Inconsistency implements ChunkOwner -{ - public static final Message INCONSISTENT_CHUNK_MESSAGE = new Message("inconsistent.chunk", "This chunk is inconsistent."); - public static final Inconsistency INSTANCE = new Inconsistency(); - public static final WorldDim WORLD = new WorldDim(-10000, "inconsistency", "Inconsistent"); - private static MineCity mineCity; - private static Island island; - private static City city; - private Inconsistency(){} - - public static Nature nature(WorldDim world) - { - VoidStorage voidStorage = new VoidStorage(); - try - { - return new Nature(mineCity, world, INCONSISTENT_CHUNK_MESSAGE, voidStorage, voidStorage, true); - } - catch(DataSourceException unexpected) - { - throw new RuntimeException(unexpected); - } - } - - public static void setMineCity(MineCity mineCity) - { - Inconsistency.mineCity = mineCity; - } - - public static City getInconsistentCity(MineCity mineCity) - { - if(city == null) - { - try - { - VoidStorage voidStorage = new VoidStorage(); - synchronized(WORLD) - { - city = new City(mineCity, "#inconsistent", "#Inconsistency", null, new BlockPos(WORLD, 0, 0, 0), - -1000, voidStorage, voidStorage, null, new Tax(0,0), 0, 0 - ); - } - } - catch(DataSourceException unexpected) - { - throw new RuntimeException(unexpected); - } - Arrays.asList(PermissionFlag.values()).forEach(f-> city.deny(f, INCONSISTENT_CHUNK_MESSAGE)); - city.allow(PermissionFlag.LEAVE); - } - return city; - } - - public static ClaimedChunk claim(ChunkPos pos) - { - Nature nature = pos.world.nature; - if(nature != null) - getInconsistentCity(nature.mineCity); - else - getInconsistentCity(); - - ClaimedChunk chunk = new ClaimedChunk(INSTANCE, pos); - chunk.invalidate(); - return chunk; - } - - public static City getInconsistentCity() - { - return getInconsistentCity(mineCity); - } - - public static Island getInconsistentIsland(MineCity mineCity) - { - if(island == null) - getInconsistentCity(mineCity); - return island; - } - - public static Island getInconsistentIsland() - { - return getInconsistentIsland(mineCity); - } - - private static class InconsistentIsland extends Island - { - public InconsistentIsland(VoidStorage storage) - { - super(Inconsistency.city, storage, storage, -1, WORLD, Collections.emptySet()); - } - - @NotNull - @Override - public City getCity() - { - City c = Inconsistency.city; - if(c == null) - synchronized(WORLD) - { - return city; - } - - return c; - } - - @Override - public int getSizeX() - { - return 0; - } - - @Override - public int getSizeZ() - { - return 0; - } - - @Override - public int getChunkCount() - { - return 0; - } - } - - private static class VoidStorage implements ICityStorage, IExceptPermissionStorage, INatureStorage - { - @NotNull - @Override - public Collection loadIslands(City city) throws DataSourceException - { - if(Inconsistency.city == null) - Inconsistency.city = city; - return Collections.singleton(island = new InconsistentIsland(this)); - } - - @Override - public void setOwner(@NotNull City city, @NotNull OptionalPlayer owner) - throws DataSourceException, IllegalStateException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void setSpawn(@NotNull City city, @NotNull BlockPos spawn) - throws DataSourceException, IllegalStateException - { - throw new DataSourceException("Inconsistent city!"); - } - - @NotNull - @Override - public Island createIsland(@NotNull City city, @NotNull ChunkPos chunk) - throws DataSourceException, IllegalStateException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void claim(@NotNull Island island, @NotNull ChunkPos chunk) - throws DataSourceException, IllegalStateException, ClassCastException - { - throw new DataSourceException("Inconsistent city!"); - } - - @NotNull - @Override - public Island claim(@NotNull Set islands, @NotNull ChunkPos chunk) - throws DataSourceException, IllegalStateException, NoSuchElementException, ClassCastException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void deleteIsland(@NotNull Island island) - throws DataSourceException, IllegalArgumentException, ClassCastException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void deleteCity(@NotNull City city) throws DataSourceException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void disclaim(@NotNull ChunkPos chunk, @NotNull Island island) - throws DataSourceException, IllegalArgumentException - { - throw new DataSourceException("Inconsistent city!"); - } - - @NotNull - @Override - public Collection disclaim(@NotNull ChunkPos chunk, @NotNull Island island, - @NotNull Set> groups) - throws DataSourceException, IllegalStateException, NoSuchElementException, ClassCastException, IllegalArgumentException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void setName(@NotNull City city, @NotNull String identity, @NotNull String name) - throws DataSourceException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void setName(@NotNull Group group, @NotNull String identity, @NotNull String name) - throws DataSourceException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void addMember(@NotNull Group group, @NotNull Identity member) - throws DataSourceException, UnsupportedOperationException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void removeMember(@NotNull Group group, @NotNull Identity member) - throws DataSourceException, UnsupportedOperationException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void addManager(@NotNull Group group, @NotNull PlayerID manager) throws DataSourceException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void removeManager(@NotNull Group group, @NotNull PlayerID manager) throws DataSourceException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void deleteGroup(@NotNull Group group) throws DataSourceException - { - throw new DataSourceException("Inconsistent city!"); - } - - @NotNull - @Override - public Collection reserve(@NotNull IslandArea reserve) throws DataSourceException - { - throw new DataSourceException("Inconsistent city!"); - } - - @NotNull - @Override - public Group createGroup(@NotNull City city, @NotNull String id, @NotNull String name) - throws DataSourceException - { - throw new DataSourceException("Inconsistent city!"); - } - - @NotNull - @Override - public Collection loadGroups(@NotNull City city) throws DataSourceException - { - if(city.getId() != -1000) - throw new DataSourceException("Inconsistent city!"); - return Collections.emptyList(); - } - - @Override - public void setDefaultMessage(@NotNull SimpleFlagHolder holder, @Nullable Message message) - throws DataSourceException - { - if(holder != city) - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void deny(@NotNull SimpleFlagHolder holder, @NotNull PermissionFlag flag, @Nullable Message message) - throws DataSourceException - { - if(holder != city) - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void denyAll(SimpleFlagHolder holder, Map flags) - throws DataSourceException - { - if(holder != city) - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void allow(@NotNull SimpleFlagHolder holder, @NotNull PermissionFlag flag) throws DataSourceException - { - if(holder != city) - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void allowAll(@NotNull SimpleFlagHolder holder) throws DataSourceException - { - if(holder != city) - throw new DataSourceException("Inconsistent city!"); - } - - @NotNull - @Override - public EnumMap loadSimplePermissions(@NotNull SimpleFlagHolder holder) - throws DataSourceException - { - EnumMap result = new EnumMap<>(PermissionFlag.class); - Arrays.stream(PermissionFlag.values()).forEach(f-> result.put(f, INCONSISTENT_CHUNK_MESSAGE)); - return result; - } - - @Override - public void set(@NotNull ExceptFlagHolder holder, @NotNull PermissionFlag flag, boolean allow, - @NotNull Identity identity, @Nullable Message message) throws DataSourceException - { - if(holder != city) - throw new UncheckedDataSourceException(new DataSourceException("Inconsistent city!")); - } - - @Override - public void remove(@NotNull ExceptFlagHolder holder, @NotNull PermissionFlag flag, - @NotNull Identity identity) - throws DataSourceException - { - if(holder != city) - throw new DataSourceException("Inconsistent city!"); - } - - @NotNull - @Override - public Map, Optional>> loadExceptPermissions(@NotNull ExceptFlagHolder holder) - throws DataSourceException - { - return Collections.emptyMap(); - } - - @Override - public int createPlot(Plot plot) throws DataSourceException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void setOwner(@NotNull Plot plot, @Nullable PlayerID owner) - throws DataSourceException, IllegalStateException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void setShape(@NotNull Plot plot, @NotNull Shape shape, BlockPos spawn, @NotNull Island newIsland) throws DataSourceException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void setName(@NotNull Plot plot, @NotNull String identity, @NotNull String name) - throws DataSourceException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void setSpawn(@NotNull Plot plot, @NotNull BlockPos spawn) throws DataSourceException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void deletePlot(@NotNull Plot plot) throws DataSourceException - { - throw new DataSourceException("Inconsistent city!"); - } - - @NotNull - @Override - public Set loadPlots(@NotNull Island island) throws DataSourceException - { - throw new DataSourceException("Inconsistent city!"); - } - - @Override - public void setCityCreationDenied(@NotNull Nature nature, boolean denied) throws DataSourceException - { - throw new DataSourceException("Inconsistent nature!"); - } - - @Override - public void setName(@NotNull Nature nature, @NotNull String name) throws DataSourceException - { - throw new DataSourceException("Inconsistent nature!"); - } - - @Override - public double invested(@NotNull City city, double value) throws DataSourceException - { - throw new DataSourceException("Inconsistent nature!"); - } - - @Override - public double invested(@NotNull Plot plot, double value) throws DataSourceException - { - throw new DataSourceException("Inconsistent nature!"); - } - - @Override - public void setInvestment(@NotNull Plot plot, double investment) throws DataSourceException - { - throw new DataSourceException("Inconsistent nature!"); - } - - @Override - public void setPrice(@NotNull City city, double price) throws DataSourceException - { - throw new DataSourceException("Inconsistent nature!"); - } - - @Override - public void setPrice(@NotNull Plot plot, double price) throws DataSourceException - { - throw new DataSourceException("Inconsistent nature!"); - } - } - - @Override - public String toString() - { - return "#Inconsistency!"; - } -} +package br.com.gamemods.minecity.structure; + +import br.com.gamemods.minecity.MineCity; +import br.com.gamemods.minecity.api.PlayerID; +import br.com.gamemods.minecity.api.command.Message; +import br.com.gamemods.minecity.api.permission.*; +import br.com.gamemods.minecity.api.shape.Shape; +import br.com.gamemods.minecity.api.world.BlockPos; +import br.com.gamemods.minecity.api.world.ChunkPos; +import br.com.gamemods.minecity.api.world.WorldDim; +import br.com.gamemods.minecity.datasource.api.DataSourceException; +import br.com.gamemods.minecity.datasource.api.ICityStorage; +import br.com.gamemods.minecity.datasource.api.IExceptPermissionStorage; +import br.com.gamemods.minecity.datasource.api.INatureStorage; +import br.com.gamemods.minecity.datasource.api.unchecked.UncheckedDataSourceException; +import br.com.gamemods.minecity.economy.Tax; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class Inconsistency implements ChunkOwner +{ + public static final Message INCONSISTENT_CHUNK_MESSAGE = new Message("inconsistent.chunk", "This chunk is inconsistent."); + public static final Inconsistency INSTANCE = new Inconsistency(); + public static final WorldDim WORLD = new WorldDim(-10000, "inconsistency", "Inconsistent"); + private static MineCity mineCity; + private static Island island; + private static City city; + private Inconsistency(){} + + public static Nature nature(WorldDim world) + { + VoidStorage voidStorage = new VoidStorage(); + try + { + return new Nature(mineCity, world, INCONSISTENT_CHUNK_MESSAGE, voidStorage, voidStorage, true); + } + catch(DataSourceException unexpected) + { + throw new RuntimeException(unexpected); + } + } + + public static void setMineCity(MineCity mineCity) + { + Inconsistency.mineCity = mineCity; + } + + public static City getInconsistentCity(MineCity mineCity) + { + if(city == null) + { + try + { + VoidStorage voidStorage = new VoidStorage(); + synchronized(WORLD) + { + city = new City(mineCity, "#inconsistent", "#Inconsistency", null, new BlockPos(WORLD, 0, 0, 0), + -1000, voidStorage, voidStorage, null, new Tax(0,0), 0, 0 + ); + } + } + catch(DataSourceException unexpected) + { + throw new RuntimeException(unexpected); + } + Arrays.asList(PermissionFlag.values()).forEach(f-> city.deny(f, INCONSISTENT_CHUNK_MESSAGE)); + city.allow(PermissionFlag.LEAVE); + } + return city; + } + + public static ClaimedChunk claim(ChunkPos pos) + { + Nature nature = pos.world.nature; + if(nature != null) + getInconsistentCity(nature.mineCity); + else + getInconsistentCity(); + + ClaimedChunk chunk = new ClaimedChunk(INSTANCE, pos); + chunk.invalidate(); + return chunk; + } + + public static City getInconsistentCity() + { + return getInconsistentCity(mineCity); + } + + public static Island getInconsistentIsland(MineCity mineCity) + { + if(island == null) + getInconsistentCity(mineCity); + return island; + } + + public static Island getInconsistentIsland() + { + return getInconsistentIsland(mineCity); + } + + private static class InconsistentIsland extends Island + { + public InconsistentIsland(VoidStorage storage) + { + super(Inconsistency.city, storage, storage, -1, WORLD, Collections.emptySet()); + } + + @NotNull + @Override + public City getCity() + { + City c = Inconsistency.city; + if(c == null) + synchronized(WORLD) + { + return city; + } + + return c; + } + + @Override + public int getSizeX() + { + return 0; + } + + @Override + public int getSizeZ() + { + return 0; + } + + @Override + public int getChunkCount() + { + return 0; + } + } + + private static class VoidStorage implements ICityStorage, IExceptPermissionStorage, INatureStorage + { + @NotNull + @Override + public Collection loadIslands(City city) throws DataSourceException + { + if(Inconsistency.city == null) + Inconsistency.city = city; + return Collections.singleton(island = new InconsistentIsland(this)); + } + + @Override + public void setOwner(@NotNull City city, @NotNull OptionalPlayer owner) + throws DataSourceException, IllegalStateException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void setSpawn(@NotNull City city, @NotNull BlockPos spawn) + throws DataSourceException, IllegalStateException + { + throw new DataSourceException("Inconsistent city!"); + } + + @NotNull + @Override + public Island createIsland(@NotNull City city, @NotNull ChunkPos chunk) + throws DataSourceException, IllegalStateException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void claim(@NotNull Island island, @NotNull ChunkPos chunk) + throws DataSourceException, IllegalStateException, ClassCastException + { + throw new DataSourceException("Inconsistent city!"); + } + + @NotNull + @Override + public Island claim(@NotNull Set islands, @NotNull ChunkPos chunk) + throws DataSourceException, IllegalStateException, NoSuchElementException, ClassCastException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void deleteIsland(@NotNull Island island) + throws DataSourceException, IllegalArgumentException, ClassCastException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void deleteCity(@NotNull City city) throws DataSourceException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void disclaim(@NotNull ChunkPos chunk, @NotNull Island island) + throws DataSourceException, IllegalArgumentException + { + throw new DataSourceException("Inconsistent city!"); + } + + @NotNull + @Override + public Collection disclaim(@NotNull ChunkPos chunk, @NotNull Island island, + @NotNull Set> groups) + throws DataSourceException, IllegalStateException, NoSuchElementException, ClassCastException, IllegalArgumentException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void setName(@NotNull City city, @NotNull String identity, @NotNull String name) + throws DataSourceException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void setName(@NotNull Group group, @NotNull String identity, @NotNull String name) + throws DataSourceException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void addMember(@NotNull Group group, @NotNull Identity member) + throws DataSourceException, UnsupportedOperationException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void removeMember(@NotNull Group group, @NotNull Identity member) + throws DataSourceException, UnsupportedOperationException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void addManager(@NotNull Group group, @NotNull PlayerID manager) throws DataSourceException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void removeManager(@NotNull Group group, @NotNull PlayerID manager) throws DataSourceException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void deleteGroup(@NotNull Group group) throws DataSourceException + { + throw new DataSourceException("Inconsistent city!"); + } + + @NotNull + @Override + public Collection reserve(@NotNull IslandArea reserve) throws DataSourceException + { + throw new DataSourceException("Inconsistent city!"); + } + + @NotNull + @Override + public Group createGroup(@NotNull City city, @NotNull String id, @NotNull String name) + throws DataSourceException + { + throw new DataSourceException("Inconsistent city!"); + } + + @NotNull + @Override + public Collection loadGroups(@NotNull City city) throws DataSourceException + { + if(city.getId() != -1000) + throw new DataSourceException("Inconsistent city!"); + return Collections.emptyList(); + } + + @Override + public void setDefaultMessage(@NotNull SimpleFlagHolder holder, @Nullable Message message) + throws DataSourceException + { + if(holder != city) + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void deny(@NotNull SimpleFlagHolder holder, @NotNull PermissionFlag flag, @Nullable Message message) + throws DataSourceException + { + if(holder != city) + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void denyAll(SimpleFlagHolder holder, Map flags) + throws DataSourceException + { + if(holder != city) + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void allow(@NotNull SimpleFlagHolder holder, @NotNull PermissionFlag flag) throws DataSourceException + { + if(holder != city) + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void allowAll(@NotNull SimpleFlagHolder holder) throws DataSourceException + { + if(holder != city) + throw new DataSourceException("Inconsistent city!"); + } + + @NotNull + @Override + public EnumMap loadSimplePermissions(@NotNull SimpleFlagHolder holder) + throws DataSourceException + { + EnumMap result = new EnumMap<>(PermissionFlag.class); + Arrays.stream(PermissionFlag.values()).forEach(f-> result.put(f, INCONSISTENT_CHUNK_MESSAGE)); + return result; + } + + @Override + public void set(@NotNull ExceptFlagHolder holder, @NotNull PermissionFlag flag, boolean allow, + @NotNull Identity identity, @Nullable Message message) throws DataSourceException + { + if(holder != city) + throw new UncheckedDataSourceException(new DataSourceException("Inconsistent city!")); + } + + @Override + public void remove(@NotNull ExceptFlagHolder holder, @NotNull PermissionFlag flag, + @NotNull Identity identity) + throws DataSourceException + { + if(holder != city) + throw new DataSourceException("Inconsistent city!"); + } + + @NotNull + @Override + public Map, Optional>> loadExceptPermissions(@NotNull ExceptFlagHolder holder) + throws DataSourceException + { + return Collections.emptyMap(); + } + + @Override + public int createPlot(Plot plot) throws DataSourceException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void setOwner(@NotNull Plot plot, @Nullable PlayerID owner) + throws DataSourceException, IllegalStateException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void setShape(@NotNull Plot plot, @NotNull Shape shape, BlockPos spawn, @NotNull Island newIsland) throws DataSourceException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void setName(@NotNull Plot plot, @NotNull String identity, @NotNull String name) + throws DataSourceException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void setSpawn(@NotNull Plot plot, @NotNull BlockPos spawn) throws DataSourceException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void deletePlot(@NotNull Plot plot) throws DataSourceException + { + throw new DataSourceException("Inconsistent city!"); + } + + @NotNull + @Override + public Set loadPlots(@NotNull Island island) throws DataSourceException + { + throw new DataSourceException("Inconsistent city!"); + } + + @Override + public void setCityCreationDenied(@NotNull Nature nature, boolean denied) throws DataSourceException + { + throw new DataSourceException("Inconsistent nature!"); + } + + @Override + public void setName(@NotNull Nature nature, @NotNull String name) throws DataSourceException + { + throw new DataSourceException("Inconsistent nature!"); + } + + @Override + public double invested(@NotNull City city, double value) throws DataSourceException + { + throw new DataSourceException("Inconsistent nature!"); + } + + @Override + public double invested(@NotNull Plot plot, double value) throws DataSourceException + { + throw new DataSourceException("Inconsistent nature!"); + } + + @Override + public void setInvestment(@NotNull Plot plot, double investment) throws DataSourceException + { + throw new DataSourceException("Inconsistent nature!"); + } + + @Override + public void setPrice(@NotNull City city, double price) throws DataSourceException + { + throw new DataSourceException("Inconsistent nature!"); + } + + @Override + public void setPrice(@NotNull Plot plot, double price) throws DataSourceException + { + throw new DataSourceException("Inconsistent nature!"); + } + } + + @Override + public String toString() + { + return "#Inconsistency!"; + } +} diff --git a/Core/src/main/java/br/com/gamemods/minecity/structure/Island.java b/Core/src/main/java/br/com/gamemods/minecity/structure/Island.java index 3f2017a6..c9cb16dc 100644 --- a/Core/src/main/java/br/com/gamemods/minecity/structure/Island.java +++ b/Core/src/main/java/br/com/gamemods/minecity/structure/Island.java @@ -1,170 +1,170 @@ -package br.com.gamemods.minecity.structure; - -import br.com.gamemods.minecity.api.PlayerID; -import br.com.gamemods.minecity.api.Slow; -import br.com.gamemods.minecity.api.StringUtil; -import br.com.gamemods.minecity.api.shape.Shape; -import br.com.gamemods.minecity.api.world.BlockPos; -import br.com.gamemods.minecity.api.world.ChunkPos; -import br.com.gamemods.minecity.api.world.WorldDim; -import br.com.gamemods.minecity.datasource.api.DataSourceException; -import br.com.gamemods.minecity.datasource.api.ICityStorage; -import br.com.gamemods.minecity.datasource.api.IExceptPermissionStorage; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.*; -import java.util.stream.Stream; - -public abstract class Island implements ChunkOwner -{ - public final Reserve reserve = new Reserve(this); - - @NotNull - protected final ICityStorage storage; - - @NotNull - protected final IExceptPermissionStorage permissionStorage; - public final int id; - public final WorldDim world; - protected Map plots; - @NotNull - protected City city; - - public Island(@NotNull City city, @NotNull ICityStorage storage, @NotNull IExceptPermissionStorage permissionStorage, - int id, WorldDim world, Set plots) - { - this.city = city; - this.storage = storage; - this.permissionStorage = permissionStorage; - this.id = id; - this.world = world; - this.plots = new HashMap<>(plots.size()); - plots.forEach(plot -> this.plots.put(plot.getIdentityName(), plot)); - } - - public Island(@NotNull City city, @NotNull ICityStorage storage, @NotNull IExceptPermissionStorage permissionStorage, - int id, WorldDim world) - throws DataSourceException - { - this.city = city; - this.storage = storage; - this.permissionStorage = permissionStorage; - this.id = id; - this.world = world; - - Set plots = storage.loadPlots(this); - this.plots = new HashMap<>(plots.size()); - plots.forEach(plot -> this.plots.put(plot.getIdentityName(), plot)); - } - - @Slow - public Plot createPlot(@NotNull String name, @Nullable PlayerID owner, @NotNull BlockPos spawn, @NotNull Shape shape) - throws DataSourceException - { - String identity = StringUtil.identity(name); - for(Island island : getCity().islands()) - { - Plot conflict = island.plots.get(identity); - if(conflict != null) - throw new IllegalArgumentException("The name "+name+" conflicts with "+conflict.getName()); - } - - if(!spawn.world.equals(world)) - throw new IllegalArgumentException("The spawn is in a different world"); - - Plot plot = new Plot(storage, permissionStorage, this, identity, name, owner, spawn, shape); - plots.put(identity, plot); - return plot; - } - - public Optional getPlot(String name) - { - return Optional.ofNullable(plots.get(StringUtil.identity(name))); - } - - public Collection getPlots() - { - return Collections.unmodifiableCollection(plots.values()); - } - - public Stream getPlotsAt(ChunkPos pos) - { - if(!pos.world.equals(world)) - return Stream.empty(); - - return plots.values().stream().filter(plot -> plot.getShape().affects(pos)); - } - - public Optional getPlotAt(BlockPos pos) - { - if(!pos.world.equals(world)) - return Optional.empty(); - - for(Plot plot : plots.values()) - if(plot.getShape().contains(pos.x, pos.y, pos.z)) - return Optional.of(plot); - - return Optional.empty(); - } - - public Stream getPlotNames() - { - return plots.values().stream().map(Plot::getName); - } - - public Set getPlotIdNames() - { - return Collections.unmodifiableSet(plots.keySet()); - } - - public final int getId() - { - return id; - } - - @NotNull - public final WorldDim getWorld() - { - return world; - } - - @NotNull - public City getCity() - { - return city; - } - - protected void setCity(@NotNull City city) - { - this.city = city; - } - - public abstract int getSizeX(); - public abstract int getSizeZ(); - public abstract int getChunkCount(); - - public IslandArea getArea() throws DataSourceException - { - return getCity().mineCity.dataSource.getArea(this); - } - - @Override - public String toString() - { - return "Island{" + - "id=" + id + - ", world=" + world + - ", city=" + getCity().getName() + - '}'; - } - - public Optional searchPlot(String name) - { - Optional plot = getPlot(name); - if(plot.isPresent()) - return plot; - - return getCity().getPlot(name); - } -} +package br.com.gamemods.minecity.structure; + +import br.com.gamemods.minecity.api.PlayerID; +import br.com.gamemods.minecity.api.Slow; +import br.com.gamemods.minecity.api.StringUtil; +import br.com.gamemods.minecity.api.shape.Shape; +import br.com.gamemods.minecity.api.world.BlockPos; +import br.com.gamemods.minecity.api.world.ChunkPos; +import br.com.gamemods.minecity.api.world.WorldDim; +import br.com.gamemods.minecity.datasource.api.DataSourceException; +import br.com.gamemods.minecity.datasource.api.ICityStorage; +import br.com.gamemods.minecity.datasource.api.IExceptPermissionStorage; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.stream.Stream; + +public abstract class Island implements ChunkOwner +{ + public final Reserve reserve = new Reserve(this); + + @NotNull + protected final ICityStorage storage; + + @NotNull + protected final IExceptPermissionStorage permissionStorage; + public final int id; + public final WorldDim world; + protected Map plots; + @NotNull + protected City city; + + public Island(@NotNull City city, @NotNull ICityStorage storage, @NotNull IExceptPermissionStorage permissionStorage, + int id, WorldDim world, Set plots) + { + this.city = city; + this.storage = storage; + this.permissionStorage = permissionStorage; + this.id = id; + this.world = world; + this.plots = new HashMap<>(plots.size()); + plots.forEach(plot -> this.plots.put(plot.getIdentityName(), plot)); + } + + public Island(@NotNull City city, @NotNull ICityStorage storage, @NotNull IExceptPermissionStorage permissionStorage, + int id, WorldDim world) + throws DataSourceException + { + this.city = city; + this.storage = storage; + this.permissionStorage = permissionStorage; + this.id = id; + this.world = world; + + Set plots = storage.loadPlots(this); + this.plots = new HashMap<>(plots.size()); + plots.forEach(plot -> this.plots.put(plot.getIdentityName(), plot)); + } + + @Slow + public Plot createPlot(@NotNull String name, @Nullable PlayerID owner, @NotNull BlockPos spawn, @NotNull Shape shape) + throws DataSourceException + { + String identity = StringUtil.identity(name); + for(Island island : getCity().islands()) + { + Plot conflict = island.plots.get(identity); + if(conflict != null) + throw new IllegalArgumentException("The name "+name+" conflicts with "+conflict.getName()); + } + + if(!spawn.world.equals(world)) + throw new IllegalArgumentException("The spawn is in a different world"); + + Plot plot = new Plot(storage, permissionStorage, this, identity, name, owner, spawn, shape); + plots.put(identity, plot); + return plot; + } + + public Optional getPlot(String name) + { + return Optional.ofNullable(plots.get(StringUtil.identity(name))); + } + + public Collection getPlots() + { + return Collections.unmodifiableCollection(plots.values()); + } + + public Stream getPlotsAt(ChunkPos pos) + { + if(!pos.world.equals(world)) + return Stream.empty(); + + return plots.values().stream().filter(plot -> plot.getShape().affects(pos)); + } + + public Optional getPlotAt(BlockPos pos) + { + if(!pos.world.equals(world)) + return Optional.empty(); + + for(Plot plot : plots.values()) + if(plot.getShape().contains(pos.x, pos.y, pos.z)) + return Optional.of(plot); + + return Optional.empty(); + } + + public Stream getPlotNames() + { + return plots.values().stream().map(Plot::getName); + } + + public Set getPlotIdNames() + { + return Collections.unmodifiableSet(plots.keySet()); + } + + public final int getId() + { + return id; + } + + @NotNull + public final WorldDim getWorld() + { + return world; + } + + @NotNull + public City getCity() + { + return city; + } + + protected void setCity(@NotNull City city) + { + this.city = city; + } + + public abstract int getSizeX(); + public abstract int getSizeZ(); + public abstract int getChunkCount(); + + public IslandArea getArea() throws DataSourceException + { + return getCity().mineCity.dataSource.getArea(this); + } + + @Override + public String toString() + { + return "Island{" + + "id=" + id + + ", world=" + world + + ", city=" + getCity().getName() + + '}'; + } + + public Optional searchPlot(String name) + { + Optional plot = getPlot(name); + if(plot.isPresent()) + return plot; + + return getCity().getPlot(name); + } +} diff --git a/Core/src/main/java/br/com/gamemods/minecity/structure/Nature.java b/Core/src/main/java/br/com/gamemods/minecity/structure/Nature.java index 91f149da..c74bb8a2 100644 --- a/Core/src/main/java/br/com/gamemods/minecity/structure/Nature.java +++ b/Core/src/main/java/br/com/gamemods/minecity/structure/Nature.java @@ -1,112 +1,112 @@ -package br.com.gamemods.minecity.structure; - -import br.com.gamemods.minecity.MineCity; -import br.com.gamemods.minecity.api.Slow; -import br.com.gamemods.minecity.api.command.Message; -import br.com.gamemods.minecity.api.permission.NatureID; -import br.com.gamemods.minecity.api.world.WorldDim; -import br.com.gamemods.minecity.datasource.api.DataSourceException; -import br.com.gamemods.minecity.datasource.api.INatureStorage; -import br.com.gamemods.minecity.datasource.api.ISimplePermissionStorage; -import br.com.gamemods.minecity.datasource.api.SimpleStorageHolder; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public final class Nature extends SimpleStorageHolder implements ChunkOwner -{ - @NotNull - private final INatureStorage storage; - - @NotNull - public final MineCity mineCity; - - @NotNull - public final WorldDim world; - - @NotNull - private final NatureID id; - - private boolean valid = true; - private boolean denyCityCreation; - - public Nature(@NotNull MineCity mineCity, @NotNull WorldDim world, - @NotNull INatureStorage storage, @NotNull ISimplePermissionStorage permissionStorage) - { - this.storage = storage; - this.permissionStorage = permissionStorage; - this.mineCity = mineCity; - this.world = world; - this.id = new NatureID(world); - - defaultMessages = mineCity.defaultNatureFlags.getDefaultMessages(); - denyAll(mineCity.defaultNatureFlags); - } - - public Nature(@NotNull MineCity mineCity, @NotNull WorldDim world, @Nullable Message defaultDenialMessage, - @NotNull INatureStorage storage, @NotNull ISimplePermissionStorage permissionStorage, - boolean denyCityCreation) - throws DataSourceException - { - super(defaultDenialMessage); - this.mineCity = mineCity; - this.permissionStorage = permissionStorage; - this.storage = storage; - this.world = world; - this.id = new NatureID(world); - this.denyCityCreation = denyCityCreation; - - defaultMessages = mineCity.defaultNatureFlags.getDefaultMessages(); - loadPermissions(); - } - - @Slow - public void setName(String name) throws DataSourceException - { - if(!valid) - throw new IllegalStateException(); - - storage.setName(this, name); - world.name = name; - } - - @Slow - public void setCityCreationDenied(boolean denied) - throws IllegalStateException, DataSourceException - { - if(!valid) - throw new IllegalStateException(); - - storage.setCityCreationDenied(this, denied); - denyCityCreation = denied; - } - - public boolean isCityCreationDenied() - { - return denyCityCreation; - } - - public void invalidate() - { - valid = false; - } - - public boolean isValid() - { - return valid; - } - - @NotNull - @Override - public NatureID owner() - { - return id; - } - - @Override - public String toString() - { - return "Nature{" + - "world=" + world + - '}'; - } -} +package br.com.gamemods.minecity.structure; + +import br.com.gamemods.minecity.MineCity; +import br.com.gamemods.minecity.api.Slow; +import br.com.gamemods.minecity.api.command.Message; +import br.com.gamemods.minecity.api.permission.NatureID; +import br.com.gamemods.minecity.api.world.WorldDim; +import br.com.gamemods.minecity.datasource.api.DataSourceException; +import br.com.gamemods.minecity.datasource.api.INatureStorage; +import br.com.gamemods.minecity.datasource.api.ISimplePermissionStorage; +import br.com.gamemods.minecity.datasource.api.SimpleStorageHolder; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class Nature extends SimpleStorageHolder implements ChunkOwner +{ + @NotNull + private final INatureStorage storage; + + @NotNull + public final MineCity mineCity; + + @NotNull + public final WorldDim world; + + @NotNull + private final NatureID id; + + private boolean valid = true; + private boolean denyCityCreation; + + public Nature(@NotNull MineCity mineCity, @NotNull WorldDim world, + @NotNull INatureStorage storage, @NotNull ISimplePermissionStorage permissionStorage) + { + this.storage = storage; + this.permissionStorage = permissionStorage; + this.mineCity = mineCity; + this.world = world; + this.id = new NatureID(world); + + defaultMessages = mineCity.defaultNatureFlags.getDefaultMessages(); + denyAll(mineCity.defaultNatureFlags); + } + + public Nature(@NotNull MineCity mineCity, @NotNull WorldDim world, @Nullable Message defaultDenialMessage, + @NotNull INatureStorage storage, @NotNull ISimplePermissionStorage permissionStorage, + boolean denyCityCreation) + throws DataSourceException + { + super(defaultDenialMessage); + this.mineCity = mineCity; + this.permissionStorage = permissionStorage; + this.storage = storage; + this.world = world; + this.id = new NatureID(world); + this.denyCityCreation = denyCityCreation; + + defaultMessages = mineCity.defaultNatureFlags.getDefaultMessages(); + loadPermissions(); + } + + @Slow + public void setName(String name) throws DataSourceException + { + if(!valid) + throw new IllegalStateException(); + + storage.setName(this, name); + world.name = name; + } + + @Slow + public void setCityCreationDenied(boolean denied) + throws IllegalStateException, DataSourceException + { + if(!valid) + throw new IllegalStateException(); + + storage.setCityCreationDenied(this, denied); + denyCityCreation = denied; + } + + public boolean isCityCreationDenied() + { + return denyCityCreation; + } + + public void invalidate() + { + valid = false; + } + + public boolean isValid() + { + return valid; + } + + @NotNull + @Override + public NatureID owner() + { + return id; + } + + @Override + public String toString() + { + return "Nature{" + + "world=" + world + + '}'; + } +} diff --git a/Core/src/test/java/br/com/gamemods/minecity/MineCityTest.java b/Core/src/test/java/br/com/gamemods/minecity/MineCityTest.java index 4360914e..fd5312fd 100644 --- a/Core/src/test/java/br/com/gamemods/minecity/MineCityTest.java +++ b/Core/src/test/java/br/com/gamemods/minecity/MineCityTest.java @@ -1,70 +1,70 @@ -package br.com.gamemods.minecity; - -import br.com.gamemods.minecity.api.world.BlockPos; -import br.com.gamemods.minecity.api.world.ChunkPos; -import br.com.gamemods.minecity.api.world.WorldDim; -import br.com.gamemods.minecity.datasource.test.TestData; -import br.com.gamemods.minecity.structure.City; -import br.com.gamemods.minecity.structure.ClaimedChunk; -import br.com.gamemods.minecity.structure.Nature; -import org.junit.Before; -import org.junit.Test; - -import java.util.Optional; - -import static org.junit.Assert.*; - -public class MineCityTest -{ - private TestData test; - private City city; - private BlockPos spawn; - - @Before - public void setUp() throws Exception - { - test = new TestData(); - spawn = new BlockPos(test.overWorld, 0,64,0); - city = new City(test.mineCity, "Test City", test.joserobjr, spawn, 0); - test.mineCity.loadChunk(city.getSpawn().getChunk()); - } - - @Test - public void testGetChunk() throws Exception - { - BlockPos off = spawn.subtract(1, 0, 1); - assertEquals(Optional.empty(), test.mineCity.getChunk(off)); - - Optional expected = Optional.of(new ClaimedChunk(test.mineCity.nature(spawn.world), off.getChunk())); - assertEquals(Optional.empty(), test.mineCity.getChunk(off)); - - assertEquals(expected.get(), test.mineCity.loadChunk(off.getChunk())); - assertEquals(expected, test.mineCity.getChunk(off)); - - ChunkPos chunk = spawn.getChunk(); - expected = Optional.of(new ClaimedChunk(city.islands().iterator().next(), chunk)); - assertEquals(expected, test.mineCity.getChunk(spawn)); - assertEquals(expected, test.mineCity.getChunk(chunk)); - - test.mineCity.unloadChunk(off.getChunk()); - assertEquals(Optional.empty(), test.mineCity.getChunk(off)); - } - - @Test - public void testGetNature() throws Exception - { - WorldDim nether = new WorldDim(-1, "nether", "Nether"); - assertNull(test.mineCity.getNature(nether)); - - Nature nature = test.mineCity.nature(nether); - assertNotNull(nature); - assertEquals(test.mineCity.getNature(nether), nature); - ChunkPos pos = new ChunkPos(nether, 0, 0); - ClaimedChunk claim = test.mineCity.loadChunk(pos); - assertNotNull(claim); - assertEquals(nature, claim.owner); - assertEquals(test.mineCity.unloadNature(nether), nature); - assertNull(test.mineCity.getNature(nether)); - assertEquals(Optional.empty(), test.mineCity.getChunk(pos)); - } +package br.com.gamemods.minecity; + +import br.com.gamemods.minecity.api.world.BlockPos; +import br.com.gamemods.minecity.api.world.ChunkPos; +import br.com.gamemods.minecity.api.world.WorldDim; +import br.com.gamemods.minecity.datasource.test.TestData; +import br.com.gamemods.minecity.structure.City; +import br.com.gamemods.minecity.structure.ClaimedChunk; +import br.com.gamemods.minecity.structure.Nature; +import org.junit.Before; +import org.junit.Test; + +import java.util.Optional; + +import static org.junit.Assert.*; + +public class MineCityTest +{ + private TestData test; + private City city; + private BlockPos spawn; + + @Before + public void setUp() throws Exception + { + test = new TestData(); + spawn = new BlockPos(test.overWorld, 0,64,0); + city = new City(test.mineCity, "Test City", test.joserobjr, spawn, 0); + test.mineCity.loadChunk(city.getSpawn().getChunk()); + } + + @Test + public void testGetChunk() throws Exception + { + BlockPos off = spawn.subtract(1, 0, 1); + assertEquals(Optional.empty(), test.mineCity.getChunk(off)); + + Optional expected = Optional.of(new ClaimedChunk(test.mineCity.nature(spawn.world), off.getChunk())); + assertEquals(Optional.empty(), test.mineCity.getChunk(off)); + + assertEquals(expected.get(), test.mineCity.loadChunk(off.getChunk())); + assertEquals(expected, test.mineCity.getChunk(off)); + + ChunkPos chunk = spawn.getChunk(); + expected = Optional.of(new ClaimedChunk(city.islands().iterator().next(), chunk)); + assertEquals(expected, test.mineCity.getChunk(spawn)); + assertEquals(expected, test.mineCity.getChunk(chunk)); + + test.mineCity.unloadChunk(off.getChunk()); + assertEquals(Optional.empty(), test.mineCity.getChunk(off)); + } + + @Test + public void testGetNature() throws Exception + { + WorldDim nether = new WorldDim(-1, "nether", "Nether"); + assertNull(test.mineCity.getNature(nether)); + + Nature nature = test.mineCity.nature(nether); + assertNotNull(nature); + assertEquals(test.mineCity.getNature(nether), nature); + ChunkPos pos = new ChunkPos(nether, 0, 0); + ClaimedChunk claim = test.mineCity.loadChunk(pos); + assertNotNull(claim); + assertEquals(nature, claim.owner); + assertEquals(test.mineCity.unloadNature(nether), nature); + assertNull(test.mineCity.getNature(nether)); + assertEquals(Optional.empty(), test.mineCity.getChunk(pos)); + } } \ No newline at end of file diff --git a/Core/src/test/java/br/com/gamemods/minecity/api/StringUtilTest.java b/Core/src/test/java/br/com/gamemods/minecity/api/StringUtilTest.java index 9cb90555..2c388152 100644 --- a/Core/src/test/java/br/com/gamemods/minecity/api/StringUtilTest.java +++ b/Core/src/test/java/br/com/gamemods/minecity/api/StringUtilTest.java @@ -1,19 +1,14 @@ package br.com.gamemods.minecity.api; -import org.assertj.core.internal.cglib.core.Local; import org.junit.Test; -import org.mockito.internal.matchers.And; -import org.mockito.internal.matchers.Contains; -import org.mockito.internal.matchers.Or; import java.text.DateFormat; import java.text.NumberFormat; -import java.util.Arrays; import java.util.Date; import java.util.Locale; import static br.com.gamemods.minecity.api.StringUtil.*; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; public class StringUtilTest { diff --git a/Core/src/test/java/br/com/gamemods/minecity/structure/CityTest.java b/Core/src/test/java/br/com/gamemods/minecity/structure/CityTest.java index aaef7a10..a261be93 100644 --- a/Core/src/test/java/br/com/gamemods/minecity/structure/CityTest.java +++ b/Core/src/test/java/br/com/gamemods/minecity/structure/CityTest.java @@ -1,314 +1,314 @@ -package br.com.gamemods.minecity.structure; - -import br.com.gamemods.minecity.api.PlayerID; -import br.com.gamemods.minecity.api.world.BlockPos; -import br.com.gamemods.minecity.api.world.ChunkPos; -import br.com.gamemods.minecity.api.world.Direction; -import br.com.gamemods.minecity.datasource.api.DataSourceException; -import br.com.gamemods.minecity.datasource.test.TestData; -import org.junit.Before; -import org.junit.Test; - -import java.util.*; - -import static com.github.kolorobot.exceptions.java8.AssertJThrowableAssert.assertThrown; -import static org.junit.Assert.*; - -public class CityTest -{ - private TestData test; - @Before - public void setUp() throws Exception - { - test = new TestData(); - } - - @Test - @SuppressWarnings("SpellCheckingInspection") - public void testDisclaim() throws Exception - { - BlockPos spawn = new BlockPos(test.overWorld, 200,64,100); - ChunkPos spawnChunk = spawn.getChunk(); - City city = new City(test.mineCity, "Disclaim", test.joserobjr, spawn, 0); - Island spawnIsland = city.islands().iterator().next(); - - assertThrown(()-> city.disclaim(spawnChunk, false)) - .isInstanceOf(IllegalStateException.class) - .hasMessageContaining("last"); - - - ChunkPos chunk = spawnChunk.add(Direction.NORTH); - assertEquals(spawnIsland, city.claim(chunk, false)); - - assertThrown(()-> city.disclaim(spawnChunk, false)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("spawn"); - - assertThrown(()-> city.claim(spawnChunk, false)) - .hasMessageContaining("reserved") - .isInstanceOf(IllegalArgumentException.class); - - assertEquals(Collections.singleton(spawnIsland), city.disclaim(chunk, false)); - assertEquals(1, city.getSizeX()); - assertEquals(1, city.getSizeZ()); - assertEquals(1, city.getChunkCount()); - - chunk = spawnChunk.add(Direction.SOUTH, 5); - Island islandA = city.claim(chunk, true); - assertNotEquals(spawnIsland, islandA); - assertEquals(2, city.getSizeX()); - assertEquals(2, city.getSizeZ()); - assertEquals(2, city.getChunkCount()); - assertEquals(Arrays.asList(spawnIsland, islandA), new ArrayList<>(city.islands())); - - assertEquals(Collections.singleton(islandA), city.disclaim(chunk, false)); - assertEquals(1, city.getSizeX()); - assertEquals(1, city.getSizeZ()); - assertEquals(1, city.getChunkCount()); - assertEquals(Collections.singletonList(spawnIsland), new ArrayList<>(city.islands())); - - Island islandB = city.claim(chunk, true); - assertNotEquals(islandA, islandB); - assertEquals(2, city.getSizeX()); - assertEquals(2, city.getSizeZ()); - assertEquals(2, city.getChunkCount()); - assertEquals(Arrays.asList(spawnIsland, islandB), new ArrayList<>(city.islands())); - - assertEquals(islandB, city.claim(chunk.add(Direction.EAST), false)); - assertEquals(3, city.getSizeX()); - assertEquals(2, city.getSizeZ()); - assertEquals(3, city.getChunkCount()); - assertEquals(Collections.singleton(islandB), city.disclaim(chunk.add(Direction.EAST), false)); - assertEquals(2, city.getSizeX()); - assertEquals(2, city.getSizeZ()); - assertEquals(2, city.getChunkCount()); - - /* - * X → - * 123456789 - * Z-1| X | - * ↓ 0| XX | - * 1| XXDXXXX | - * 4| X | - * 5| XX | - * 6| X | - */ - assertEquals(islandB, city.claim(chunk.add(Direction.EAST), false)); - chunk = chunk.add(Direction.EAST, 2); - assertEquals(islandB, city.claim(chunk, false)); - assertEquals(islandB, city.claim(chunk.add(Direction.EAST), false)); - assertEquals(islandB, city.claim(chunk.add(Direction.EAST, 2), false)); - assertEquals(islandB, city.claim(chunk.add(Direction.EAST, 3), false)); - assertEquals(islandB, city.claim(chunk.add(Direction.EAST, 4), false)); - assertEquals(islandB, city.claim(chunk.add(Direction.NORTH), false)); - assertEquals(islandB, city.claim(chunk.add(Direction.NORTH, 2), false)); - assertEquals(islandB, city.claim(chunk.add(Direction.NORTH_EAST), false)); - assertEquals(islandB, city.claim(chunk.add(Direction.SOUTH), false)); - assertEquals(islandB, city.claim(chunk.add(Direction.SOUTH, 2), false)); - assertEquals(islandB, city.claim(chunk.add(Direction.SOUTH, 2).add(Direction.EAST), false)); - assertEquals(islandB, city.claim(chunk.add(Direction.SOUTH, 3), false)); - assertEquals(14, islandB.getChunkCount()); - assertEquals(7, islandB.getSizeX()); - assertEquals(6, islandB.getSizeZ()); - assertEquals(15, city.getChunkCount()); - assertEquals(8, city.getSizeX()); - assertEquals(7, city.getSizeZ()); - assertEquals(2, city.islands().size()); - - /* - * X → - * 123456789 - * Z-1| B | - * ↓ 0| BB | - * 1| XX BBBB | - * 4| Y | - * 5| YY | - * 6| Y | - */ - ChunkPos pos = chunk; - assertThrown(()-> city.disclaim(pos, false)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("required"); - - Collection islands = city.disclaim(pos, true); - assertEquals(2, islands.size()); - Island islandX = islands.stream().min((a,b)-> a.getChunkCount()-b.getChunkCount()).get(); - Island islandY = islands.stream().filter(i-> i != islandX).findAny().get(); - assertEquals(2, islandX.getChunkCount()); - assertEquals(4, islandY.getChunkCount()); - assertEquals(7, islandB.getChunkCount()); - assertEquals(5, islandB.getSizeX()); - assertEquals(3, islandB.getSizeZ()); - assertEquals(14, city.getChunkCount()); - assertEquals(10, city.getSizeX()); - assertEquals(8, city.getSizeZ()); - assertEquals(4, city.islands().size()); - - city.islands().forEach(island -> assertEquals(island, city.getIsland(island.getId()))); - } - - @Test - public void testCreateCity() throws DataSourceException - { - BlockPos spawn = new BlockPos(test.overWorld, 0, 64, 0); - test.mineCity.loadNature(spawn.world); - test.mineCity.loadChunk(spawn.getChunk()); - - City city = new City(test.mineCity, "Test City", test.joserobjr, spawn, 0); - assertTrue(city.getId() > 0); - assertEquals(test.joserobjr, city.owner()); - assertEquals(spawn, city.getSpawn()); - assertEquals(1, city.getSizeX()); - assertEquals(1, city.getSizeZ()); - assertEquals(1, city.getChunkCount()); - assertEquals(1, city.islands().size()); - assertEquals("Test City", city.getName()); - assertEquals(city, test.mineCity.getChunk(spawn.getChunk()).flatMap(ClaimedChunk::getCity).orElse(null)); - - Island island = city.islands().iterator().next(); - assertEquals(city, island.getCity()); - assertEquals(1, island.getSizeX()); - assertEquals(1, island.getSizeZ()); - assertEquals(1, island.getChunkCount()); - assertTrue(island.getId() > 0); - assertEquals(island, city.getIsland(island.getId())); - - assertEquals(test.mineCity.loadChunk(city.getSpawn().getChunk()), new ClaimedChunk( - island, city.getSpawn().getChunk())); - - assertThrown(()-> new City(test.mineCity, "Bad City", test.joserobjr, spawn, 0)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("reserved"); - - } - - @Test - public void testSetId() throws Exception - { - City badCity = new City(test.mineCity, "Bad City", test.joserobjr, new BlockPos(test.overWorld, 400,40, 65), 0); - assertThrown(()-> badCity.setId(-3)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("id = "+-3); - assertThrown(()-> badCity.setId(3)) - .isInstanceOf(IllegalStateException.class) - .hasMessageContaining("change"); - } - - @Test - public void testSetName() throws Exception - { - City first = new City(test.mineCity, "First City", test.joserobjr, new BlockPos(test.overWorld, -598, 44, -998), 0); - //noinspection SpellCheckingInspection - assertEquals("firstcity", first.getIdentityName()); - assertThrown(()-> new City(test.mineCity, "first_ciTy!", test.joserobjr, new BlockPos(test.overWorld, 98988,55,9874), 0)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("taken"); - - City second = new City(test.mineCity, "City 2", test.joserobjr, new BlockPos(test.overWorld, 788,68,9885), 0); - assertEquals("city2", second.getIdentityName()); - first.setName("City1"); - assertEquals("city1", first.getIdentityName()); - assertEquals("City1", first.getName()); - - assertThrown(() -> first.setName("CITY2")) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("taken"); - first.setName("CITY 1"); - assertEquals("city1", first.getIdentityName()); - assertEquals("CITY 1", first.getName()); - - assertThrown(()-> first.setName("c1")) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("Bad"); - - assertThrown(()-> new City(test.mineCity, "c1", test.joserobjr, new BlockPos(test.overWorld, 5846487,4,448), 0)); - } - - @Test - public void testSetSpawn() throws Exception - { - BlockPos spawn = new BlockPos(test.overWorld, 54648, 32, 5855); - City spawnCity = new City(test.mineCity, "SpawnCity", test.joserobjr, spawn, 0); - - assertEquals(spawn, spawnCity.getSpawn()); - assertThrown(()-> spawnCity.setSpawn(spawn.getChunk().add(Direction.EAST).getMaxBlock())) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("not part of the city"); - - BlockPos newSpawn = spawn.getChunk().getMaxBlock(); - spawnCity.setSpawn(newSpawn); - assertEquals(newSpawn, spawnCity.getSpawn()); - } - - @Test - public void testSetOwner() throws Exception - { - City owned = new City(test.mineCity, "Owned", test.joserobjr, new BlockPos(test.overWorld, 456484878, 32, 445454), 0); - - assertEquals(test.joserobjr, owned.owner()); - PlayerID newOwner = new PlayerID(UUID.randomUUID(), "Randy"); - owned.setOwner(newOwner); - assertEquals(newOwner, owned.owner()); - } - - @Test - public void testClaim() throws DataSourceException - { - BlockPos spawn = new BlockPos(test.overWorld, 250, 32, -200); - ChunkPos chunk = spawn.getChunk(); - City city = new City(test.mineCity, "City 2", test.joserobjr, spawn, 0); - - Island islandA = city.islands().iterator().next(); - assertEquals(islandA, city.claim(chunk.add(Direction.NORTH), false)); - assertEquals(2, islandA.getChunkCount()); - assertEquals(2, islandA.getSizeZ()); - assertEquals(1, islandA.getSizeX()); - assertEquals(2, city.getChunkCount()); - assertEquals(2, city.getSizeZ()); - assertEquals(1, city.getSizeX()); - - assertEquals(islandA, city.claim(chunk.add(Direction.WEST), false)); - assertEquals(3, islandA.getChunkCount()); - assertEquals(2, islandA.getSizeZ()); - assertEquals(2, islandA.getSizeX()); - assertEquals(3, city.getChunkCount()); - assertEquals(2, city.getSizeZ()); - assertEquals(2, city.getSizeX()); - - Island islandB = city.claim(chunk.add(Direction.EAST, 2), true); - assertNotEquals(islandA, islandB); - assertEquals(1, islandB.getChunkCount()); - assertEquals(1, islandB.getSizeZ()); - assertEquals(1, islandB.getSizeX()); - assertEquals(4, city.getChunkCount()); - assertEquals(3, city.getSizeZ()); - assertEquals(3, city.getSizeX()); - assertEquals(2, city.islands().size()); - - assertEquals(islandA, city.claim(chunk.add(Direction.EAST), false)); - assertEquals(5, islandA.getChunkCount()); - assertEquals(2, islandA.getSizeZ()); - assertEquals(4, islandA.getSizeX()); - assertEquals(5, city.getChunkCount()); - assertEquals(2, city.getSizeZ()); - assertEquals(4, city.getSizeX()); - assertEquals(1, city.islands().size()); - assertEquals(0, islandB.getChunkCount()); - assertEquals(0, islandB.getSizeX()); - assertEquals(0, islandB.getSizeX()); - } - - @Test - public void testClaimIsland() throws Exception - { - City farCity = new City(test.mineCity, "FarCity", test.joserobjr, new BlockPos(test.overWorld, 655,55,488), 0); - - BlockPos far = new BlockPos(test.overWorld, -4847,44,688); - assertThrown(()-> farCity.claim(far.getChunk(), false)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("not touching"); - - farCity.claim(far.getChunk(), true); - assertEquals(2, farCity.islands().size()); - } +package br.com.gamemods.minecity.structure; + +import br.com.gamemods.minecity.api.PlayerID; +import br.com.gamemods.minecity.api.world.BlockPos; +import br.com.gamemods.minecity.api.world.ChunkPos; +import br.com.gamemods.minecity.api.world.Direction; +import br.com.gamemods.minecity.datasource.api.DataSourceException; +import br.com.gamemods.minecity.datasource.test.TestData; +import org.junit.Before; +import org.junit.Test; + +import java.util.*; + +import static com.github.kolorobot.exceptions.java8.AssertJThrowableAssert.assertThrown; +import static org.junit.Assert.*; + +public class CityTest +{ + private TestData test; + @Before + public void setUp() throws Exception + { + test = new TestData(); + } + + @Test + @SuppressWarnings("SpellCheckingInspection") + public void testDisclaim() throws Exception + { + BlockPos spawn = new BlockPos(test.overWorld, 200,64,100); + ChunkPos spawnChunk = spawn.getChunk(); + City city = new City(test.mineCity, "Disclaim", test.joserobjr, spawn, 0); + Island spawnIsland = city.islands().iterator().next(); + + assertThrown(()-> city.disclaim(spawnChunk, false)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("last"); + + + ChunkPos chunk = spawnChunk.add(Direction.NORTH); + assertEquals(spawnIsland, city.claim(chunk, false)); + + assertThrown(()-> city.disclaim(spawnChunk, false)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("spawn"); + + assertThrown(()-> city.claim(spawnChunk, false)) + .hasMessageContaining("reserved") + .isInstanceOf(IllegalArgumentException.class); + + assertEquals(Collections.singleton(spawnIsland), city.disclaim(chunk, false)); + assertEquals(1, city.getSizeX()); + assertEquals(1, city.getSizeZ()); + assertEquals(1, city.getChunkCount()); + + chunk = spawnChunk.add(Direction.SOUTH, 5); + Island islandA = city.claim(chunk, true); + assertNotEquals(spawnIsland, islandA); + assertEquals(2, city.getSizeX()); + assertEquals(2, city.getSizeZ()); + assertEquals(2, city.getChunkCount()); + assertEquals(Arrays.asList(spawnIsland, islandA), new ArrayList<>(city.islands())); + + assertEquals(Collections.singleton(islandA), city.disclaim(chunk, false)); + assertEquals(1, city.getSizeX()); + assertEquals(1, city.getSizeZ()); + assertEquals(1, city.getChunkCount()); + assertEquals(Collections.singletonList(spawnIsland), new ArrayList<>(city.islands())); + + Island islandB = city.claim(chunk, true); + assertNotEquals(islandA, islandB); + assertEquals(2, city.getSizeX()); + assertEquals(2, city.getSizeZ()); + assertEquals(2, city.getChunkCount()); + assertEquals(Arrays.asList(spawnIsland, islandB), new ArrayList<>(city.islands())); + + assertEquals(islandB, city.claim(chunk.add(Direction.EAST), false)); + assertEquals(3, city.getSizeX()); + assertEquals(2, city.getSizeZ()); + assertEquals(3, city.getChunkCount()); + assertEquals(Collections.singleton(islandB), city.disclaim(chunk.add(Direction.EAST), false)); + assertEquals(2, city.getSizeX()); + assertEquals(2, city.getSizeZ()); + assertEquals(2, city.getChunkCount()); + + /* + * X → + * 123456789 + * Z-1| X | + * ↓ 0| XX | + * 1| XXDXXXX | + * 4| X | + * 5| XX | + * 6| X | + */ + assertEquals(islandB, city.claim(chunk.add(Direction.EAST), false)); + chunk = chunk.add(Direction.EAST, 2); + assertEquals(islandB, city.claim(chunk, false)); + assertEquals(islandB, city.claim(chunk.add(Direction.EAST), false)); + assertEquals(islandB, city.claim(chunk.add(Direction.EAST, 2), false)); + assertEquals(islandB, city.claim(chunk.add(Direction.EAST, 3), false)); + assertEquals(islandB, city.claim(chunk.add(Direction.EAST, 4), false)); + assertEquals(islandB, city.claim(chunk.add(Direction.NORTH), false)); + assertEquals(islandB, city.claim(chunk.add(Direction.NORTH, 2), false)); + assertEquals(islandB, city.claim(chunk.add(Direction.NORTH_EAST), false)); + assertEquals(islandB, city.claim(chunk.add(Direction.SOUTH), false)); + assertEquals(islandB, city.claim(chunk.add(Direction.SOUTH, 2), false)); + assertEquals(islandB, city.claim(chunk.add(Direction.SOUTH, 2).add(Direction.EAST), false)); + assertEquals(islandB, city.claim(chunk.add(Direction.SOUTH, 3), false)); + assertEquals(14, islandB.getChunkCount()); + assertEquals(7, islandB.getSizeX()); + assertEquals(6, islandB.getSizeZ()); + assertEquals(15, city.getChunkCount()); + assertEquals(8, city.getSizeX()); + assertEquals(7, city.getSizeZ()); + assertEquals(2, city.islands().size()); + + /* + * X → + * 123456789 + * Z-1| B | + * ↓ 0| BB | + * 1| XX BBBB | + * 4| Y | + * 5| YY | + * 6| Y | + */ + ChunkPos pos = chunk; + assertThrown(()-> city.disclaim(pos, false)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("required"); + + Collection islands = city.disclaim(pos, true); + assertEquals(2, islands.size()); + Island islandX = islands.stream().min((a,b)-> a.getChunkCount()-b.getChunkCount()).get(); + Island islandY = islands.stream().filter(i-> i != islandX).findAny().get(); + assertEquals(2, islandX.getChunkCount()); + assertEquals(4, islandY.getChunkCount()); + assertEquals(7, islandB.getChunkCount()); + assertEquals(5, islandB.getSizeX()); + assertEquals(3, islandB.getSizeZ()); + assertEquals(14, city.getChunkCount()); + assertEquals(10, city.getSizeX()); + assertEquals(8, city.getSizeZ()); + assertEquals(4, city.islands().size()); + + city.islands().forEach(island -> assertEquals(island, city.getIsland(island.getId()))); + } + + @Test + public void testCreateCity() throws DataSourceException + { + BlockPos spawn = new BlockPos(test.overWorld, 0, 64, 0); + test.mineCity.loadNature(spawn.world); + test.mineCity.loadChunk(spawn.getChunk()); + + City city = new City(test.mineCity, "Test City", test.joserobjr, spawn, 0); + assertTrue(city.getId() > 0); + assertEquals(test.joserobjr, city.owner()); + assertEquals(spawn, city.getSpawn()); + assertEquals(1, city.getSizeX()); + assertEquals(1, city.getSizeZ()); + assertEquals(1, city.getChunkCount()); + assertEquals(1, city.islands().size()); + assertEquals("Test City", city.getName()); + assertEquals(city, test.mineCity.getChunk(spawn.getChunk()).flatMap(ClaimedChunk::getCity).orElse(null)); + + Island island = city.islands().iterator().next(); + assertEquals(city, island.getCity()); + assertEquals(1, island.getSizeX()); + assertEquals(1, island.getSizeZ()); + assertEquals(1, island.getChunkCount()); + assertTrue(island.getId() > 0); + assertEquals(island, city.getIsland(island.getId())); + + assertEquals(test.mineCity.loadChunk(city.getSpawn().getChunk()), new ClaimedChunk( + island, city.getSpawn().getChunk())); + + assertThrown(()-> new City(test.mineCity, "Bad City", test.joserobjr, spawn, 0)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("reserved"); + + } + + @Test + public void testSetId() throws Exception + { + City badCity = new City(test.mineCity, "Bad City", test.joserobjr, new BlockPos(test.overWorld, 400,40, 65), 0); + assertThrown(()-> badCity.setId(-3)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("id = "+-3); + assertThrown(()-> badCity.setId(3)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("change"); + } + + @Test + public void testSetName() throws Exception + { + City first = new City(test.mineCity, "First City", test.joserobjr, new BlockPos(test.overWorld, -598, 44, -998), 0); + //noinspection SpellCheckingInspection + assertEquals("firstcity", first.getIdentityName()); + assertThrown(()-> new City(test.mineCity, "first_ciTy!", test.joserobjr, new BlockPos(test.overWorld, 98988,55,9874), 0)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("taken"); + + City second = new City(test.mineCity, "City 2", test.joserobjr, new BlockPos(test.overWorld, 788,68,9885), 0); + assertEquals("city2", second.getIdentityName()); + first.setName("City1"); + assertEquals("city1", first.getIdentityName()); + assertEquals("City1", first.getName()); + + assertThrown(() -> first.setName("CITY2")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("taken"); + first.setName("CITY 1"); + assertEquals("city1", first.getIdentityName()); + assertEquals("CITY 1", first.getName()); + + assertThrown(()-> first.setName("c1")) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Bad"); + + assertThrown(()-> new City(test.mineCity, "c1", test.joserobjr, new BlockPos(test.overWorld, 5846487,4,448), 0)); + } + + @Test + public void testSetSpawn() throws Exception + { + BlockPos spawn = new BlockPos(test.overWorld, 54648, 32, 5855); + City spawnCity = new City(test.mineCity, "SpawnCity", test.joserobjr, spawn, 0); + + assertEquals(spawn, spawnCity.getSpawn()); + assertThrown(()-> spawnCity.setSpawn(spawn.getChunk().add(Direction.EAST).getMaxBlock())) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("not part of the city"); + + BlockPos newSpawn = spawn.getChunk().getMaxBlock(); + spawnCity.setSpawn(newSpawn); + assertEquals(newSpawn, spawnCity.getSpawn()); + } + + @Test + public void testSetOwner() throws Exception + { + City owned = new City(test.mineCity, "Owned", test.joserobjr, new BlockPos(test.overWorld, 456484878, 32, 445454), 0); + + assertEquals(test.joserobjr, owned.owner()); + PlayerID newOwner = new PlayerID(UUID.randomUUID(), "Randy"); + owned.setOwner(newOwner); + assertEquals(newOwner, owned.owner()); + } + + @Test + public void testClaim() throws DataSourceException + { + BlockPos spawn = new BlockPos(test.overWorld, 250, 32, -200); + ChunkPos chunk = spawn.getChunk(); + City city = new City(test.mineCity, "City 2", test.joserobjr, spawn, 0); + + Island islandA = city.islands().iterator().next(); + assertEquals(islandA, city.claim(chunk.add(Direction.NORTH), false)); + assertEquals(2, islandA.getChunkCount()); + assertEquals(2, islandA.getSizeZ()); + assertEquals(1, islandA.getSizeX()); + assertEquals(2, city.getChunkCount()); + assertEquals(2, city.getSizeZ()); + assertEquals(1, city.getSizeX()); + + assertEquals(islandA, city.claim(chunk.add(Direction.WEST), false)); + assertEquals(3, islandA.getChunkCount()); + assertEquals(2, islandA.getSizeZ()); + assertEquals(2, islandA.getSizeX()); + assertEquals(3, city.getChunkCount()); + assertEquals(2, city.getSizeZ()); + assertEquals(2, city.getSizeX()); + + Island islandB = city.claim(chunk.add(Direction.EAST, 2), true); + assertNotEquals(islandA, islandB); + assertEquals(1, islandB.getChunkCount()); + assertEquals(1, islandB.getSizeZ()); + assertEquals(1, islandB.getSizeX()); + assertEquals(4, city.getChunkCount()); + assertEquals(3, city.getSizeZ()); + assertEquals(3, city.getSizeX()); + assertEquals(2, city.islands().size()); + + assertEquals(islandA, city.claim(chunk.add(Direction.EAST), false)); + assertEquals(5, islandA.getChunkCount()); + assertEquals(2, islandA.getSizeZ()); + assertEquals(4, islandA.getSizeX()); + assertEquals(5, city.getChunkCount()); + assertEquals(2, city.getSizeZ()); + assertEquals(4, city.getSizeX()); + assertEquals(1, city.islands().size()); + assertEquals(0, islandB.getChunkCount()); + assertEquals(0, islandB.getSizeX()); + assertEquals(0, islandB.getSizeX()); + } + + @Test + public void testClaimIsland() throws Exception + { + City farCity = new City(test.mineCity, "FarCity", test.joserobjr, new BlockPos(test.overWorld, 655,55,488), 0); + + BlockPos far = new BlockPos(test.overWorld, -4847,44,688); + assertThrown(()-> farCity.claim(far.getChunk(), false)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("not touching"); + + farCity.claim(far.getChunk(), true); + assertEquals(2, farCity.islands().size()); + } } \ No newline at end of file diff --git a/Forge/1.10.2/build.gradle b/Forge/1.10.2/build.gradle index e45f2463..15f2b71b 100644 --- a/Forge/1.10.2/build.gradle +++ b/Forge/1.10.2/build.gradle @@ -2,16 +2,26 @@ // For those who want the bleeding edge buildscript { repositories { + mavenCentral() jcenter() maven { name = "forge" - url = "http://files.minecraftforge.net/maven" + url = "https://maven.minecraftforge.net/" + } + maven { + name = "forge2" + url = "https://files.minecraftforge.net/maven" + } + maven { + name = "sonatype" + url = "https://oss.sonatype.org/content/repositories/snapshots/" } } dependencies { classpath 'net.minecraftforge.gradle:ForgeGradle:2.2-SNAPSHOT' } } + apply plugin: 'net.minecraftforge.gradle.forge' /* @@ -23,12 +33,12 @@ plugins { project(':Forge:1.10.2') { archivesBaseName = "MineCity-Forge-MC1.10.2" - sourceCompatibility = 1.8 - targetCompatibility = 1.8 + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } minecraft { - version = "1.10.2-12.18.2.2151" + version = "1.10.2-12.18.3.2511" runDir = "run" clientJvmArgs += "-Dfml.coreMods.load=br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod" @@ -39,7 +49,7 @@ minecraft { // stable_# stables are built at the discretion of the MCP team. // Use non-default mappings at your own risk. they may not allways work. // simply re-run your setup task after changing the mappings to update your workspace. - mappings = "snapshot_20160518" + mappings = "snapshot_20161111" // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. } @@ -56,11 +66,11 @@ repositories { dependencies { shade project(':Core') shade project(':Forge:Base') - compile "mysql:mysql-connector-java:6.0.3" - compile "li.cil.oc:OpenComputers:MC1.10.2-1.6.+:api" - compile "net.industrial-craft:industrialcraft-2:2.6.+:dev" - testCompile fileTree(dir: "run/mods", include: ["*.jar"], exclude:["*Assets*"]) - testCompile fileTree(dir: "run/mods/1.7.10", include: ["*.jar"]) + implementation "mysql:mysql-connector-java:6.0.3" + implementation "li.cil.oc:OpenComputers:MC1.10.2-1.7.+:api" + implementation "net.industrial-craft:industrialcraft-2:2.6.+:dev" + testImplementation fileTree(dir: "run/mods", include: ["*.jar"], exclude:["*Assets*"]) + testImplementation fileTree(dir: "run/mods/1.10.2", include: ["*.jar"]) } jar { @@ -74,7 +84,7 @@ jar { configurations.shade.each { dep -> from(project.zipTree(dep)){ - include 'br/**', '*.yml', 'deps.info', 'minecity_*.cfg', 'assets/minecity/**', 'org/mcstats/**' + include 'br/**', '*.yml', 'deps.info', 'minecity_*.cfg', 'assets/minecity/**', 'org/bstats/**' } } } diff --git a/Forge/1.10.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_10_2/MineCityFrost.java b/Forge/1.10.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_10_2/MineCityFrost.java index d5decefc..2d6215e2 100644 --- a/Forge/1.10.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_10_2/MineCityFrost.java +++ b/Forge/1.10.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_10_2/MineCityFrost.java @@ -5,15 +5,12 @@ import net.minecraft.util.math.Vec3i; import net.minecraft.world.World; -public class MineCityFrost extends MineCityForge -{ - public BlockPos block(World world, Vec3i pos) - { +public class MineCityFrost extends MineCityForge { + public BlockPos block(World world, Vec3i pos) { return new BlockPos(world(world), pos.getX(), pos.getY(), pos.getZ()); } - public BlockPos block(BlockPos base, Vec3i pos) - { + public BlockPos block(BlockPos base, Vec3i pos) { return new BlockPos(base, pos.getX(), pos.getY(), pos.getZ()); } } diff --git a/Forge/1.12.2/build.gradle b/Forge/1.12.2/build.gradle new file mode 100644 index 00000000..f933ba2c --- /dev/null +++ b/Forge/1.12.2/build.gradle @@ -0,0 +1,147 @@ + +// For those who want the bleeding edge +buildscript { + repositories { + mavenCentral() + jcenter() + maven { + name = "forge" + url = "https://maven.minecraftforge.net/" + } + maven { + name = "forge2" + url = "https://files.minecraftforge.net/maven" + } + maven { + name = "sonatype" + url = "https://oss.sonatype.org/content/repositories/snapshots/" + } + } + dependencies { + classpath 'net.minecraftforge.gradle:ForgeGradle:3.+' + } +} + +apply plugin: 'net.minecraftforge.gradle' + +sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8 +compileJava { + sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8 +} +project(':Forge:1.12.2') { + archivesBaseName = "MineCity-Forge-MC1.12.2" + + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +minecraft { + // the mappings can be changed at any time, and must be in the following format. + // snapshot_YYYYMMDD snapshot are built nightly. + // stable_# stables are built at the discretion of the MCP team. + // Use non-default mappings at your own risk. they may not always work. + //mappings channel: 'snapshot', version: '20171003-1.12' + mappings channel: 'snapshot', version: '20171003-1.12' + // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. + + runs { + client { + workingDirectory project.file('run') + + jvmArg '-Dfml.coreMods.load=br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod' + + // Recommended logging data for a userdev environment + property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' + + // Recommended logging level for the console + property 'forge.logging.console.level', 'debug' + } + + server { + jvmArg '-Dfml.coreMods.load=br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod' + + // Recommended logging data for a userdev environment + property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' + + // Recommended logging level for the console + property 'forge.logging.console.level', 'debug' + } + } +} + +configurations { + shade + compile.extendsFrom shade +} + +repositories { + maven { url = "https://maven.cil.li/" } + maven { url = "https://maven.ic2.player.to/" } +} + +dependencies { + minecraft 'net.minecraftforge:forge:1.12.2-14.23.5.2859' + shade project(':Core') + shade project(':Forge:Base') + implementation "mysql:mysql-connector-java:6.0.3" + implementation "li.cil.oc:OpenComputers:MC1.12.2-1.7.+:api" + implementation "net.industrial-craft:industrialcraft-2:2.8.+:dev" + testImplementation fileTree(dir: "run/mods", include: ["*.jar"], exclude:["*Assets*"]) + testImplementation fileTree(dir: "run/mods/1.12.2", include: ["*.jar"]) +} + +jar { + manifest.attributes ( + 'FMLCorePluginContainsFMLMod': 'true', + 'ForceLoadAsMod': 'true', + "Specification-Title": "minecity", + "Specification-Vendor": "minecity", + "Specification-Version": "1", // We are version 1 of ourselves + "Implementation-Title": project.name, + "Implementation-Version": "${version}", + "Implementation-Vendor": "minecity", + "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), + 'FMLCorePlugin': 'br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod', + 'FMLAT': 'minecity_at.cfg' + ) + + configurations.shade.each { dep -> + from(project.zipTree(dep)){ + include 'br/**', '*.yml', 'deps.info', 'minecity_*.cfg', 'assets/minecity/**', 'org/bstats/**' + } + } +} + +// Example configuration to allow publishing using the maven-publish task +// This is the preferred method to reobfuscate your jar file +jar.finalizedBy('reobfJar') + +processResources { + // this will ensure that this task is redone when the versions change. + inputs.property "version", project.version + + // replace stuff in mcmod.info, nothing else + from(sourceSets.main.resources.srcDirs) { + include 'mcmod.info' + + // replace version and mcversion + expand 'version':project.version, 'mcversion': "1.12.2" + } + + // copy everything else except the mcmod.info + from(sourceSets.main.resources.srcDirs) { + exclude 'mcmod.info' + } +} + +// workaround for userdev bug +tasks.create("copyResourceToClasses", Copy.class) { + tasks.classes.dependsOn(it) + dependsOn(tasks.processResources) + onlyIf { gradle.taskGraph.hasTask(tasks.prepareRuns) } + + into("$buildDir/classes/java/main") + // if you write @Mod class in kotlin, please use code below + // into("$buildDir/classes/kotlin/main") + from(tasks.processResources.destinationDir) +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/ColorUtil.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/ColorUtil.java new file mode 100644 index 00000000..91d34af5 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/ColorUtil.java @@ -0,0 +1,38 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2; + +import br.com.gamemods.minecity.api.world.Direction; +import net.minecraft.util.EnumFacing; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.NoSuchElementException; + +public class ColorUtil { + @Nullable + public static EnumFacing toFace(Direction direction) { + switch(direction) { + case NORTH: return EnumFacing.NORTH; + case SOUTH: return EnumFacing.SOUTH; + case EAST: return EnumFacing.EAST; + case WEST: return EnumFacing.WEST; + case UP: return EnumFacing.UP; + case DOWN: return EnumFacing.DOWN; + default: return null; + } + } + + @NotNull + public static Direction toDirection(EnumFacing face) { + if(face == null) return Direction.NONE; + + switch(face) { + case NORTH: return Direction.NORTH; + case SOUTH: return Direction.SOUTH; + case EAST: return Direction.EAST; + case WEST: return Direction.WEST; + case UP: return Direction.UP; + case DOWN: return Direction.DOWN; + default: throw new NoSuchElementException(face.getName()); + } + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/MineCityColor.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/MineCityColor.java new file mode 100644 index 00000000..98491691 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/MineCityColor.java @@ -0,0 +1,16 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2; + +import br.com.gamemods.minecity.api.world.BlockPos; +import br.com.gamemods.minecity.forge.base.MineCityForge; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.World; + +public class MineCityColor extends MineCityForge { + public BlockPos block(World world, Vec3i pos) { + return new BlockPos(world(world), pos.getX(), pos.getY(), pos.getZ()); + } + + public BlockPos block(BlockPos base, Vec3i pos) { + return new BlockPos(base, pos.getX(), pos.getY(), pos.getZ()); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/ColorExplosion.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/ColorExplosion.java new file mode 100644 index 00000000..7cf71178 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/ColorExplosion.java @@ -0,0 +1,31 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.accessors; + +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntity; +import br.com.gamemods.minecity.forge.base.accessors.world.IExplosion; +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorExplosionTransformer; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorInterfaceTransformer; +import net.minecraft.world.Explosion; + +@Referenced(at = ColorInterfaceTransformer.class) +public interface ColorExplosion extends IExplosion +{ + @Override + default double getExplosionX() { + return ((Explosion) this).getPosition().x; + } + + @Override + default double getExplosionY() { + return ((Explosion) this).getPosition().y; + } + + @Override + default double getExplosionZ() { + return ((Explosion) this).getPosition().z; + } + + @Referenced(at = ColorExplosionTransformer.class) + @Override + IEntity getExploder(); +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/ColorPlayerList.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/ColorPlayerList.java new file mode 100644 index 00000000..9d4b111a --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/ColorPlayerList.java @@ -0,0 +1,40 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.accessors; + +import br.com.gamemods.minecity.forge.base.accessors.IPlayerList; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntityPlayerMP; +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorInterfaceTransformer; +import com.mojang.authlib.GameProfile; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.server.management.PlayerList; +import net.minecraft.world.Teleporter; + +import java.util.List; + +@Referenced(at = ColorInterfaceTransformer.class) +public interface ColorPlayerList extends IPlayerList { + default PlayerList getForgePlayerList() { + return (PlayerList) this; + } + + @Override + default List getPlayerEntities() { + return ((PlayerList) this).getPlayers(); + } + + @Override + @SuppressWarnings("unchecked") + default List getIPlayers() { + return (List) ((PlayerList) this).getPlayers(); + } + + @Override + default void transferToDimension(IEntityPlayerMP player, int dimension, Teleporter teleporter) { + ((PlayerList) this).transferPlayerToDimension((EntityPlayerMP) player, dimension, teleporter); + } + + @Override + default boolean isOp(GameProfile profile) { + return ((PlayerList) this).canSendCommands(profile); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/ColorRayTraceResult.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/ColorRayTraceResult.java new file mode 100644 index 00000000..092c4062 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/ColorRayTraceResult.java @@ -0,0 +1,52 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.accessors; + +import br.com.gamemods.minecity.api.shape.Point; +import br.com.gamemods.minecity.api.shape.PrecisePoint; +import br.com.gamemods.minecity.api.world.Direction; +import br.com.gamemods.minecity.api.world.WorldDim; +import br.com.gamemods.minecity.forge.base.accessors.IRayTraceResult; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntity; +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.mc_1_12_2.ColorUtil; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorInterfaceTransformer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; + +@Referenced(at = ColorInterfaceTransformer.class) +public interface ColorRayTraceResult extends IRayTraceResult { + @Override + default br.com.gamemods.minecity.api.world.BlockPos getHitBlockPos(WorldDim dim) { + BlockPos pos = ((RayTraceResult) this).getBlockPos(); + return new br.com.gamemods.minecity.api.world.BlockPos( + dim, pos.getX(), pos.getY(), pos.getZ() + ); + } + + @Override + default Point getHitBlockPos() { + BlockPos pos = ((RayTraceResult) this).getBlockPos(); + return new Point(pos.getX(), pos.getY(), pos.getZ()); + } + + @Override + default PrecisePoint getEntityPos() { + Vec3d pos = ((RayTraceResult) this).hitVec; + return new PrecisePoint(pos.x, pos.y, pos.z); + } + + @Override + default IEntity getEntity() { + return (IEntity) ((RayTraceResult) this).entityHit; + } + + @Override + default int getHitType() { + return ((RayTraceResult) this).typeOfHit.ordinal(); + } + + @Override + default Direction getHitSide() { + return ColorUtil.toDirection(((RayTraceResult) this).sideHit); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/ColorWorldServer.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/ColorWorldServer.java new file mode 100644 index 00000000..3736bc59 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/ColorWorldServer.java @@ -0,0 +1,134 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.accessors; + +import br.com.gamemods.minecity.api.shape.PreciseCuboid; +import br.com.gamemods.minecity.api.shape.PrecisePoint; +import br.com.gamemods.minecity.api.world.Direction; +import br.com.gamemods.minecity.forge.base.accessors.IRayTraceResult; +import br.com.gamemods.minecity.forge.base.accessors.block.IBlockSnapshot; +import br.com.gamemods.minecity.forge.base.accessors.block.IState; +import br.com.gamemods.minecity.forge.base.accessors.block.ITileEntity; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntity; +import br.com.gamemods.minecity.forge.base.accessors.world.IWorldServer; +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.base.tile.ITileEntityData; +import br.com.gamemods.minecity.forge.mc_1_12_2.ColorUtil; +import br.com.gamemods.minecity.forge.mc_1_12_2.accessors.block.ColorBlock; +import br.com.gamemods.minecity.forge.mc_1_12_2.accessors.block.ColorState; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorWorldServerTransformer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraftforge.common.util.BlockSnapshot; + +import java.util.List; +import java.util.stream.Collectors; + +@Referenced(at = ColorWorldServerTransformer.class) +public interface ColorWorldServer extends IWorldServer { + @Override + default ColorBlock getIBlock(int x, int y, int z) { + return getIState(x, y, z).getIBlock(); + } + + @Override + default ColorState getIState(int x, int y, int z) { + return (ColorState) ((WorldServer) this).getBlockState(new BlockPos(x, y, z)); + } + + default boolean isSideSolid(int x, int y, int z, Direction direction) { + EnumFacing side = ColorUtil.toFace(direction); + if(side == null) + return getIState(x, y, z).isOpaqueCube(); + + return ((WorldServer) this).isSideSolid(new BlockPos(x, y, z), side); + } + + default boolean isTopSolid(int x, int y, int z) { + return ((WorldServer) this).isSideSolid(new BlockPos(x, y, z), EnumFacing.UP); + } + + @Override + default boolean setBlock(int x, int y, int z, IState state) { + return ((WorldServer) this).setBlockState(new BlockPos(x, y, z), (IBlockState) state); + } + + @Override + default IRayTraceResult rayTraceBlocks(PrecisePoint start, PrecisePoint end, boolean stopOnLiquid) { + return (IRayTraceResult) ((WorldServer) this).rayTraceBlocks( + new Vec3d(start.x, start.y, start.z), + new Vec3d(end.x, end.y, end.z), + stopOnLiquid + ); + } + + @Override + default List getCollisionBoxes(PreciseCuboid cuboid) { + AxisAlignedBB box = new AxisAlignedBB( + cuboid.min.x, + cuboid.min.y, + cuboid.min.z, + cuboid.max.x, + cuboid.max.y, + cuboid.max.z + ); + + return ((WorldServer) this).getCollisionBoxes(null, box).stream().map(bb-> + new PreciseCuboid( + new PrecisePoint(bb.minX, bb.minY, bb.minZ), + new PrecisePoint(bb.maxX, bb.maxY, bb.maxZ) + ) + ).collect(Collectors.toList()); + } + + @SuppressWarnings("unchecked") + @Override + default List getEntities(PreciseCuboid cuboid) + { + AxisAlignedBB box = new AxisAlignedBB( + cuboid.min.x, + cuboid.min.y, + cuboid.min.z, + cuboid.max.x, + cuboid.max.y, + cuboid.max.z + ); + + return (List) ((WorldServer) this).getEntitiesWithinAABBExcludingEntity(null, box); + } + + @Override + default ITileEntity getTileEntity(int x, int y, int z) { + return (ITileEntity) ((WorldServer) this).getTileEntity(new BlockPos(x, y, z)); + } + + @Override + default boolean isAir(int x, int y, int z) + { + return ((WorldServer) this).isAirBlock(new BlockPos(x, y, z)); + } + + @Override + default boolean isBlockLoaded(int x, int y, int z) { + return ((WorldServer) this).isBlockLoaded(new BlockPos(x, y, z)); + } + + @Override + default IBlockSnapshot getBlockSnapshot(int x, int y, int z) { + return (IBlockSnapshot) BlockSnapshot.getBlockSnapshot((World)this, new BlockPos(x, y, z)); + } + + @Override + default void setTile(int x, int y, int z, ITileEntityData tile) { + ((WorldServer) this).setTileEntity(new BlockPos(x, y, z), (TileEntity) tile); + } + + @Override + default boolean isNormalCube(int x, int y, int z, boolean def) { + return ((WorldServer) this).isBlockNormalCube(new BlockPos(x, y, z), def); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/block/ColorBlock.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/block/ColorBlock.java new file mode 100644 index 00000000..ff0ec24c --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/block/ColorBlock.java @@ -0,0 +1,53 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.accessors.block; + +import br.com.gamemods.minecity.forge.base.accessors.block.IBlock; +import br.com.gamemods.minecity.forge.base.accessors.block.IState; +import br.com.gamemods.minecity.forge.base.accessors.item.IItem; +import br.com.gamemods.minecity.forge.base.accessors.item.IItemStack; +import br.com.gamemods.minecity.forge.base.accessors.world.IWorldServer; +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorInterfaceTransformer; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +import java.util.List; +import java.util.Random; + +@Referenced(at = ColorInterfaceTransformer.class) +public interface ColorBlock extends IBlock { + default ColorState getDefaultIState() { + return (ColorState) ((Block) this).getDefaultState(); + } + + @Override + default boolean isReplaceable(IWorldServer world, int x, int y, int z) { + return ((Block) this).isReplaceable((IBlockAccess) world, new BlockPos(x, y, z)); + } + + @Override + default IItem getItemDropped(IState state, Random rand, int fortune) { + return (IItem) getForgeBlock().getItemDropped((IBlockState) state, rand, fortune); + } + + @SuppressWarnings("deprecation") + @Override + default IItemStack getItemStack(IState state, IWorldServer world, int x, int y, int z) { + return (IItemStack)(Object) getForgeBlock().getItem((World) world, new BlockPos(x,y,z), (IBlockState) state); + } + + @SuppressWarnings("unchecked") + @Override + default List getDrops(IWorldServer world, IState state, int fortune, int x, int y, int z) { + return (List) ((Block) this).getDrops((WorldServer) world, new BlockPos(x, y, z), (IBlockState) state, fortune); + } + + @SuppressWarnings("deprecation") + @Override + default float getHardness(IState state, IWorldServer world, int x, int y, int z) { + return ((Block) this).getBlockHardness((IBlockState) state, (World) world, new BlockPos(x, y, z)); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/block/ColorBlockSnapshot.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/block/ColorBlockSnapshot.java new file mode 100644 index 00000000..e6c542d3 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/block/ColorBlockSnapshot.java @@ -0,0 +1,49 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.accessors.block; + +import br.com.gamemods.minecity.api.world.BlockPos; +import br.com.gamemods.minecity.forge.base.MineCityForge; +import br.com.gamemods.minecity.forge.base.accessors.block.IBlockSnapshot; +import br.com.gamemods.minecity.forge.base.accessors.block.IState; +import br.com.gamemods.minecity.forge.base.accessors.world.IWorldServer; +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorInterfaceTransformer; +import net.minecraftforge.common.util.BlockSnapshot; + +@Referenced(at = ColorInterfaceTransformer.class) +public interface ColorBlockSnapshot extends IBlockSnapshot { + @Override + default BlockPos getPosition(MineCityForge mod) { + net.minecraft.util.math.BlockPos pos = ((BlockSnapshot) this).getPos(); + return new BlockPos(mod.world(getIWorld()), pos.getX(), pos.getY(), pos.getZ()); + } + + @Override + default int getX() { + return ((BlockSnapshot) this).getPos().getX(); + } + + @Override + default int getY() { + return ((BlockSnapshot) this).getPos().getY(); + } + + @Override + default int getZ() { + return ((BlockSnapshot) this).getPos().getZ(); + } + + @Override + default IWorldServer getIWorld() { + return (IWorldServer) ((BlockSnapshot) this).getWorld(); + } + + @Override + default IState getCurrentState() { + return (IState) ((BlockSnapshot) this).getCurrentBlock(); + } + + @Override + default IState getReplacedState() { + return (IState) ((BlockSnapshot) this).getReplacedBlock(); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/block/ColorState.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/block/ColorState.java new file mode 100644 index 00000000..df7cd3c3 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/block/ColorState.java @@ -0,0 +1,60 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.accessors.block; + +import br.com.gamemods.minecity.forge.base.accessors.block.IProp; +import br.com.gamemods.minecity.forge.base.accessors.block.IState; +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorInterfaceTransformer; +import net.minecraft.block.Block; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.state.IBlockState; +import net.minecraftforge.registries.GameData; + +import java.util.Collection; +import java.util.Map; + +@Referenced(at = ColorInterfaceTransformer.class) +public interface ColorState extends IState { + default IBlockState getForgeState() { + return (IBlockState) this; + } + + default Block getForgeBlock() { + return ((IBlockState) this).getBlock(); + } + + default ColorBlock getIBlock() { + return (ColorBlock) ((IBlockState) this).getBlock(); + } + + default boolean isOpaqueCube() { + return getForgeState().isOpaqueCube(); + } + + @Override + default int getStateId() { + return GameData.getBlockStateIDMap().get((IBlockState) this); + } + + @SuppressWarnings("unchecked") + @Override + default Collection> getPropertyKeys() { + return (Collection) ((IBlockState) this).getPropertyKeys(); + } + + @SuppressWarnings("unchecked") + @Override + default > T getValue(IProp prop) { + return ((IBlockState) this).getValue((IProperty) prop); + } + + @SuppressWarnings("unchecked") + @Override + default Map, Comparable> getProps() { + return (Map) ((IBlockState) this).getProperties(); + } + + @Override + default boolean isSolid() { + return ((IBlockState) this).getMaterial().isSolid(); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/entity/ColorEntity.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/entity/ColorEntity.java new file mode 100644 index 00000000..7a610979 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/entity/ColorEntity.java @@ -0,0 +1,43 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.accessors.entity; + +import br.com.gamemods.minecity.forge.base.accessors.ICommander; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntity; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntityPlayerMP; +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorInterfaceTransformer; +import net.minecraft.entity.Entity; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.SPacketDestroyEntities; +import net.minecraft.network.play.server.SPacketEntityMetadata; +import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler; + +@Referenced(at = ColorInterfaceTransformer.class) +public interface ColorEntity extends IEntity, ICommander { + @Override + default boolean sendSpawnPackets(IEntityPlayerMP player) { + Entity entity = (Entity) this; + Packet pkt = FMLNetworkHandler.getEntitySpawningPacket(entity); + if(pkt == null) + return false; + + player.sendPacket(pkt); + if(!entity.getDataManager().isEmpty()) + player.sendPacket(new SPacketEntityMetadata(entity.getEntityId(), entity.getDataManager(), true)); + + continueSendingSpawnPackets(player); + return true; + } + + default void continueSendingSpawnPackets(IEntityPlayerMP player){} + + @Override + default void sendAllWatchableData(IEntityPlayerMP p) { + Entity entity = (Entity) this; + p.sendPacket(new SPacketEntityMetadata(entity.getEntityId(), entity.getDataManager(), true)); + } + + @Override + default void sendDestroyPacket(IEntityPlayerMP p) { + p.sendPacket(new SPacketDestroyEntities(((Entity)this).getEntityId())); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/entity/ColorEntityPlayerMP.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/entity/ColorEntityPlayerMP.java new file mode 100644 index 00000000..111dfe53 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/entity/ColorEntityPlayerMP.java @@ -0,0 +1,104 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.accessors.entity; + +import br.com.gamemods.minecity.api.command.Message; +import br.com.gamemods.minecity.forge.base.MineCityForge; +import br.com.gamemods.minecity.forge.base.accessors.block.IState; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntity; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntityLiving; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntityPlayerMP; +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorEntityPlayerMPTransformer; +import io.netty.buffer.Unpooled; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Blocks; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.Packet; +import net.minecraft.network.PacketBuffer; +import net.minecraft.network.play.server.*; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; + +@Referenced(at = ColorEntityPlayerMPTransformer.class) +public interface ColorEntityPlayerMP extends IEntityPlayerMP, ColorEntity { + @Override + default void sendBlock(int x, int y, int z) { + sendPacket(new SPacketBlockChange(getWorld(), new BlockPos(x, y, z))); + } + + @Override + default void sendFakeBlock(int x, int y, int z, IState state) { + PacketBuffer buffer = new PacketBuffer(Unpooled.buffer(8 + 4)); + buffer.writeBlockPos(new BlockPos(x, y, z)); + buffer.writeVarInt(0); + + try { + SPacketBlockChange packet = new SPacketBlockChange(); + packet.readPacketData(buffer); + + packet.blockState = (IBlockState) state; + sendPacket(packet); + } catch(Exception e) { + e.printStackTrace(); + } + } + + @Override + default void sendTitle(MineCityForge mod, Message title, Message subtitle) { + TextComponentString empty = new TextComponentString(""); + sendPacket(new SPacketTitle(SPacketTitle.Type.RESET, empty)); + sendPacket(new SPacketTitle(SPacketTitle.Type.TIMES, empty, 10, 70, 20)); + if(title != null) { + sendPacket(new SPacketTitle(SPacketTitle.Type.TITLE, ITextComponent.Serializer.jsonToComponent( + mod.transformer.toJson(title) + ))); + } else { + sendPacket(new SPacketTitle(SPacketTitle.Type.TITLE, empty)); + } + + if(subtitle != null) { + sendPacket(new SPacketTitle(SPacketTitle.Type.SUBTITLE, ITextComponent.Serializer.jsonToComponent( + mod.transformer.toJson(subtitle) + ))); + } + } + + @Override + default void sendTileEntity(int x, int y, int z) { + BlockPos pos = new BlockPos(x, y, z); + TileEntity tile = getWorld().getTileEntity(pos); + if(tile == null) return; + + Packet packet = tile.getUpdatePacket(); + if(packet == null) { + NBTTagCompound nbt = tile.serializeNBT(); + packet = new SPacketUpdateTileEntity(pos, 1, nbt); + } + + sendPacket(packet); + } + + @Override + default void sendFakeAir(int x, int y, int z) { + sendFakeBlock(x, y, z, (IState) Blocks.AIR.getDefaultState()); + } + + @Override + default void sendHealth() { + EntityPlayerMP player = (EntityPlayerMP) this; + sendPacket(new SPacketUpdateHealth(player.getHealth(), player.getFoodStats().getFoodLevel(), player.getFoodStats().getSaturationLevel())); + } + + @Override + default void sendLeashState(IEntityLiving entity) { + sendPacket(new SPacketEntityAttach((Entity)entity, (Entity)entity.getLeashHolder())); + } + + @Override + default void sendTeleport(IEntity entity) { + sendPacket(new SPacketEntityTeleport((Entity) entity)); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/entity/ColorPath.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/entity/ColorPath.java new file mode 100644 index 00000000..eb2ab886 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/entity/ColorPath.java @@ -0,0 +1,24 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.accessors.entity; + +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IPath; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IPathPoint; +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorInterfaceTransformer; +import net.minecraft.pathfinding.Path; + +@Referenced(at = ColorInterfaceTransformer.class) +public interface ColorPath extends IPath { + default Path getForgePath() { + return (Path) this; + } + + @Override + default boolean isFinished() { + return getForgePath().isFinished(); + } + + @Override + default IPathPoint getFinalPoint() { + return (IPathPoint) getForgePath().getFinalPathPoint(); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/item/ColorItemGlassBottle.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/item/ColorItemGlassBottle.java new file mode 100644 index 00000000..c7120831 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/accessors/item/ColorItemGlassBottle.java @@ -0,0 +1,32 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.accessors.item; + +import br.com.gamemods.minecity.api.permission.PermissionFlag; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntity; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntityPlayerMP; +import br.com.gamemods.minecity.forge.base.accessors.item.IItemGlassBottle; +import br.com.gamemods.minecity.forge.base.accessors.item.IItemStack; +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.base.protection.reaction.NoReaction; +import br.com.gamemods.minecity.forge.base.protection.reaction.Reaction; +import br.com.gamemods.minecity.forge.base.protection.reaction.SingleBlockReaction; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorInterfaceTransformer; +import net.minecraft.entity.EntityAreaEffectCloud; +import net.minecraft.entity.boss.EntityDragon; +import net.minecraft.entity.player.EntityPlayerMP; + +import java.util.List; + +@Referenced(at = ColorInterfaceTransformer.class) +public interface ColorItemGlassBottle extends IItemGlassBottle { + @Override + default Reaction reactRightClick(IEntityPlayerMP player, IItemStack stack, boolean offHand) { + EntityPlayerMP entity = (EntityPlayerMP) player; + List list = entity.world.getEntitiesWithinAABB(EntityAreaEffectCloud.class, entity.getEntityBoundingBox().expand(2, 2, 2), cloud -> + cloud != null && cloud.isEntityAlive() && cloud.getOwner() instanceof EntityDragon + ); + + if(!list.isEmpty()) return new SingleBlockReaction(((IEntity) list.get(0)).getBlockPos(player.getServer()), PermissionFlag.CLICK); + + return NoReaction.INSTANCE; + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/command/ColorTransformer.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/command/ColorTransformer.java new file mode 100644 index 00000000..e1ee172a --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/command/ColorTransformer.java @@ -0,0 +1,29 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.command; + +import br.com.gamemods.minecity.api.command.Message; +import br.com.gamemods.minecity.forge.base.accessors.ICommander; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntityPlayerMP; +import br.com.gamemods.minecity.forge.base.command.ForgeTransformer; +import net.minecraft.util.text.ITextComponent; + +import java.util.Objects; + +public class ColorTransformer extends ForgeTransformer { + @Override + public void send(Message message, ICommander commander) { + if(commander instanceof IEntityPlayerMP && !((IEntityPlayerMP) commander).hasNetHandler()) return; + + commander.getForgeSender().sendMessage(Objects.requireNonNull(ITextComponent.Serializer.jsonToComponent( + toJson(message) + ))); + } + + @Override + public void send(Message[] message, ICommander commander) { + if(commander instanceof IEntityPlayerMP && !((IEntityPlayerMP) commander).hasNetHandler()) return; + + commander.getForgeSender().sendMessage(Objects.requireNonNull(ITextComponent.Serializer.jsonToComponent( + toJson(Message.list(message, Message.LINE_BREAK)) + ))); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/MineCityColorCoreMod.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/MineCityColorCoreMod.java new file mode 100644 index 00000000..772ed6a0 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/MineCityColorCoreMod.java @@ -0,0 +1,184 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.core; + +import br.com.gamemods.minecity.forge.base.core.ModEnv; +import br.com.gamemods.minecity.forge.base.core.deploader.DepLoader; +import net.minecraft.launchwrapper.LaunchClassLoader; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.versioning.ComparableVersion; +import net.minecraftforge.fml.relauncher.FMLInjectionData; +import net.minecraftforge.fml.relauncher.IFMLCallHook; +import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; + +import java.io.File; +import java.util.Map; + +@IFMLLoadingPlugin.Name("MineCityCore") +@IFMLLoadingPlugin.MCVersion("1.12.2") +@IFMLLoadingPlugin.TransformerExclusions({ + "br.com.gamemods.minecity.forge.mc_1_12_2.core", + "br.com.gamemods.minecity.forge.base.core", +}) +@IFMLLoadingPlugin.SortingIndex(value = 1001) +public class MineCityColorCoreMod implements IFMLLoadingPlugin, IFMLCallHook { + @Override + public Void call() throws Exception { + File mcDir = (File) FMLInjectionData.data()[6]; + new DepLoader( + new File(mcDir, "MineCity/libs"), + (LaunchClassLoader) MineCityColorCoreMod.class.getClassLoader(), + FMLInjectionData.data(), + Loader.class, + ComparableVersion::new + ).load(); + return null; + } + + @Override + public String[] getASMTransformerClass() { + ModEnv.hookClass = "br.com.gamemods.minecity.forge.mc_1_12_2.protection.MineCityColorHooks"; + ModEnv.rayTraceResultClass = "net.minecraft.util.math.RayTraceResult"; + ModEnv.aabbClass = "net.minecraft.util.math.AxisAlignedBB"; + + return new String[]{ + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.mod.appeng.PartFormationPlaneTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.mod.appeng.PartAnnihilationPaneTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.appeng.IPartHostTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.appeng.AEBasePartTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.mod.appeng.PartPlacementTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.appeng.ToolMassCannonTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.appeng.WirelessTerminalGuiObjectTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.appeng.BlockTinyTNTTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.appeng.EntityTinyTNTPrimedTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.TileEntityTeleporterTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.TileEntityTerraTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.TileEntityMinerTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.TileEntityCropmatronTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.TileEntityTeslaTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.TileEntityRecyclerTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.ExplosionIC2Transformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.EntityIC2ExplosiveTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.EntityDynamiteTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.ICropTileTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.CropCardTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.TileEntityCropTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.EntityParticleTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.opencomputers.InventoryTransferDClassTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.opencomputers.TransposerTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.opencomputers.AdapterTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.opencomputers.InventoryWorldControlMk2DClassTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.opencomputers.MagnetProviderTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.opencomputers.UpgradePistonTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.opencomputers.UpgradeTractorBeamTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.opencomputers.UpgradeLeashTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.opencomputers.TankWorldControlDClassTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.opencomputers.TileRobotProxyTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.opencomputers.InventoryWorldControlDClassTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.opencomputers.TextBufferTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.opencomputers.PacketHandlerDTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.pamharvestcraft.BlockPamSaplingTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.mrcrayfishfurniture.MessageTVServerTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.wrcbe.EntityREPTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.wrcbe.JammerPartTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.wrcbe.WirelessBoltTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.zettaindustries.QuarryFixerBlockTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.zettaindustries.BlockSulfurTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.immersiveintegration.TileItemRobinTransformer", + // TODO: Check if pump still existing on 1.12 + //"br.com.gamemods.minecity.forge.base.core.transformer.mod.immersiveengineering.TileEntityFluidPumpTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.immersiveengineering.TileEntityConveyorSorterTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.immersiveengineering.BlockMetalDevicesTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.immersiveengineering.ItemIEToolTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.immersiveengineering.ChemthrowerEffectTeleportTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.immersiveengineering.ChemthrowerHandlerTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.immersiveengineering.EntityChemthrowerShotTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.forgemultipart.ButtonPartTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.mod.forgemultipart.BlockMultiPartTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.forgemultipart.EventHandlerTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.mod.ModInterfacesTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.EntityPlayerTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.EntityLivingBaseTransformer", + "br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorExplosionTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.item.ItemTransformer", + // TODO: Fix + // "br.com.gamemods.minecity.forge.base.core.transformer.forge.block.BlockPistonBaseTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.item.ItemBucketTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.block.BlockChorusFlowerTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.NodeProcessorTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.PathFinderTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.world.ChunkCacheTransformer", + // TODO: Compatibility with Sponge + //"br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.OnImpactTransformer", + // TODO: Fix + // "br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.EntityEggTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.forge.block.BlockStemTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.block.BlockSaplingTransformer", + // TODO: Fix Pure Forge issue + //"br.com.gamemods.minecity.forge.base.core.transformer.forge.block.GrowMonitorTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.block.BlockDragonEggTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.EntityXPOrbTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.EntityArrowTransformer", + // TODO: Fix Pure Forge issue + //"br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.EntityIgnitionTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.EntityEnderCrystalTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.forge.block.BlockTNTTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.EntityArmorStandTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.EntityFishingHookTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.EntityAreaEffectCloudTransformer", + "br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorInterfaceTransformer", + // TODO: Compatibility with Sponge + //"br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorEntityPotionTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.EntityBoatTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.EntityMinecartTransformer", + // TODO: Fix + //"br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorWorldServerTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.world.ChunkTransformer", + "br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorEntityPlayerMPTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.block.BlockOpenReactorTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.block.BlockClickReactorTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.block.BlockClickExtendsOpenTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.block.BlockModifyExtendsOpenTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.block.BlockNoReactExtendsOpenTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.item.ItemModifyFaceReactorTransformer", + "br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.ProjectileTransformer", + // TODO: Fix Pure Forge issue + //"br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.AddPotionEffectObserverTransformer" + }; + } + + @Override + public String getModContainerClass() { + return null; + } + + @Override + public String getSetupClass() { + return getClass().getName(); + } + + @Override + public void injectData(Map data) { + // Nothing to be injected here + } + + @Override + public String getAccessTransformerClass() { + return "br.com.gamemods.minecity.forge.base.core.transformer.MineCityAT"; + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/transformer/forge/ColorEntityPlayerMPTransformer.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/transformer/forge/ColorEntityPlayerMPTransformer.java new file mode 100644 index 00000000..638f6e9b --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/transformer/forge/ColorEntityPlayerMPTransformer.java @@ -0,0 +1,13 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge; + +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.EntityPlayerMPTransformer; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod; + +@Referenced +public class ColorEntityPlayerMPTransformer extends EntityPlayerMPTransformer { + @Referenced(at = MineCityColorCoreMod.class) + public ColorEntityPlayerMPTransformer() { + super("br.com.gamemods.minecity.forge.mc_1_12_2.accessors.entity.ColorEntityPlayerMP"); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/transformer/forge/ColorEntityPotionTransformer.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/transformer/forge/ColorEntityPotionTransformer.java new file mode 100644 index 00000000..2b59fb3b --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/transformer/forge/ColorEntityPotionTransformer.java @@ -0,0 +1,13 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge; + +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.EntityPotionTransformer; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod; + +@Referenced +public class ColorEntityPotionTransformer extends EntityPotionTransformer { + @Referenced(at = MineCityColorCoreMod.class) + public ColorEntityPotionTransformer() { + super(1); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/transformer/forge/ColorExplosionTransformer.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/transformer/forge/ColorExplosionTransformer.java new file mode 100644 index 00000000..1e0833d7 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/transformer/forge/ColorExplosionTransformer.java @@ -0,0 +1,32 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge; + +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.base.core.transformer.forge.world.ExplosionTransformer; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldNode; +import org.objectweb.asm.tree.MethodNode; + +import java.util.NoSuchElementException; + +import static org.objectweb.asm.Opcodes.*; + +@Referenced(at = MineCityColorCoreMod.class) +public class ColorExplosionTransformer extends ExplosionTransformer { + @Override + protected void patch(String name, ClassNode node, ClassReader reader) { + super.patch(name, node, reader); + + FieldNode exploder = node.fields.stream().filter(f-> f.desc.equals("Lnet/minecraft/entity/Entity;")) + .findFirst().orElseThrow(()-> new NoSuchElementException("Failed to find the exploder field")); + MethodNode method = new MethodNode(ACC_PUBLIC, "getExploder", "()Lbr.com.gamemods.minecity.forge.base.accessors.entity.base.IEntity;".replace('.','/'), null, null); + + method.visitCode(); + method.visitVarInsn(ALOAD, 0); + method.visitFieldInsn(GETFIELD, name.replace('.','/'), exploder.name, exploder.desc); + method.visitInsn(ARETURN); + method.visitEnd(); + node.methods.add(method); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/transformer/forge/ColorInterfaceTransformer.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/transformer/forge/ColorInterfaceTransformer.java new file mode 100644 index 00000000..1e2bd744 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/transformer/forge/ColorInterfaceTransformer.java @@ -0,0 +1,45 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge; + +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.base.core.transformer.forge.ForgeInterfaceTransformer; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod; + +import java.util.Map; + +@Referenced +public class ColorInterfaceTransformer extends ForgeInterfaceTransformer { + @Referenced(at = MineCityColorCoreMod.class) + public ColorInterfaceTransformer() { + Map r = getReplacements(); + + r.put("net.minecraft.pathfinding.Path", + "br.com.gamemods.minecity.forge.mc_1_12_2.accessors.entity.ColorPath"); + + r.put("net.minecraft.world.Explosion", + "br.com.gamemods.minecity.forge.mc_1_12_2.accessors.ColorExplosion"); + + r.put("net.minecraft.item.ItemGlassBottle", + "br.com.gamemods.minecity.forge.mc_1_12_2.accessors.item.ColorItemGlassBottle"); + + r.put("net.minecraftforge.common.util.BlockSnapshot", + "br.com.gamemods.minecity.forge.mc_1_12_2.accessors.block.ColorBlockSnapshot"); + + r.put("net.minecraft.block.Block", + "br.com.gamemods.minecity.forge.mc_1_12_2.accessors.block.ColorBlock"); + + r.put("net.minecraft.entity.Entity", + "br.com.gamemods.minecity.forge.mc_1_12_2.accessors.entity.ColorEntity"); + + r.put("net.minecraft.block.state.IBlockState", + "br.com.gamemods.minecity.forge.mc_1_12_2.accessors.block.ColorState"); + + r.put("net.minecraft.server.management.PlayerList", + "br.com.gamemods.minecity.forge.mc_1_12_2.accessors.ColorPlayerList"); + + r.put("net.minecraft.util.math.RayTraceResult", + "br.com.gamemods.minecity.forge.mc_1_12_2.accessors.ColorRayTraceResult"); + + setReplacements(r); + printReplacements(); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/transformer/forge/ColorWorldServerTransformer.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/transformer/forge/ColorWorldServerTransformer.java new file mode 100644 index 00000000..b6df06ef --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/core/transformer/forge/ColorWorldServerTransformer.java @@ -0,0 +1,42 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge; + +import br.com.gamemods.minecity.forge.base.core.ModEnv; +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.base.core.transformer.forge.world.WorldServerTransformer; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +@Referenced +public class ColorWorldServerTransformer extends WorldServerTransformer { + @Referenced(at = MineCityColorCoreMod.class) + public ColorWorldServerTransformer() { + super("br.com.gamemods.minecity.forge.mc_1_12_2.accessors.ColorWorldServer"); + } + + @Override + protected void patch(String name, ClassNode node, ClassReader reader) { + super.patch(name, node, reader); + + for (MethodNode method : node.methods) { + if (method.name.equals("func_175660_a") || method.name.equals("isBlockModifiable")) { + InsnList list = new InsnList(); + list.add(new VarInsnNode(ALOAD, 0)); + list.add(new VarInsnNode(ALOAD, 1)); + list.add(new VarInsnNode(ALOAD, 2)); + list.add(new MethodInsnNode(INVOKESTATIC, ModEnv.hookClass.replace('.','/'), + "canMineBlock", "(Lnet/minecraft/world/World;Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/util/math/BlockPos;)Z", false + )); + LabelNode labelNode = new LabelNode(); + list.add(new JumpInsnNode(IFEQ, labelNode)); + list.add(new InsnNode(ICONST_0)); + list.add(new InsnNode(IRETURN)); + list.add(labelNode); + method.instructions.insert(list); + break; + } + } + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/BlockGrowEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/BlockGrowEvent.java new file mode 100644 index 00000000..291c0d77 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/BlockGrowEvent.java @@ -0,0 +1,22 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.common.util.BlockSnapshot; +import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +import java.util.Collections; +import java.util.List; + +@Cancelable +public class BlockGrowEvent extends BlockEvent { + public final Object source; + public final List changes; + public BlockGrowEvent(World world, BlockPos pos, IBlockState state, Object source, List changes) { + super(world, pos, state); + this.changes = Collections.unmodifiableList(changes); + this.source = source; + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/EggSpawnChickenEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/EggSpawnChickenEvent.java new file mode 100644 index 00000000..b775d414 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/EggSpawnChickenEvent.java @@ -0,0 +1,12 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.entity.projectile.EntityEgg; +import net.minecraftforge.event.entity.EntityEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +@Cancelable +public class EggSpawnChickenEvent extends EntityEvent { + public EggSpawnChickenEvent(EntityEgg entity) { + super(entity); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/EntityDamageEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/EntityDamageEvent.java new file mode 100644 index 00000000..488be392 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/EntityDamageEvent.java @@ -0,0 +1,18 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.entity.Entity; +import net.minecraft.util.DamageSource; +import net.minecraftforge.event.entity.EntityEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +@Cancelable +public class EntityDamageEvent extends EntityEvent { + public final DamageSource source; + public final float amount; + + public EntityDamageEvent(Entity entity, DamageSource source, float amount) { + super(entity); + this.source = source; + this.amount = amount; + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/EntityIgniteEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/EntityIgniteEvent.java new file mode 100644 index 00000000..b2b91ffe --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/EntityIgniteEvent.java @@ -0,0 +1,32 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.entity.Entity; +import net.minecraftforge.event.entity.EntityEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; +import org.jetbrains.annotations.Nullable; + +import javax.annotation.Nonnull; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +@Cancelable +public class EntityIgniteEvent extends EntityEvent { + @Nullable + public final Object source; + public final Class sourceClass; + public final String sourceMethod; + public final String sourceMethodDesc; + public final int ticks; + public final List methodParams; + + public EntityIgniteEvent(Entity entity, int ticks, @Nullable Object source, Class sourceClass, String sourceMethod, String sourceMethodDesc, Object[] methodParams) { + super(entity); + this.source = source; + this.sourceClass = sourceClass; + this.sourceMethod = sourceMethod; + this.sourceMethodDesc = sourceMethodDesc; + this.ticks = ticks; + this.methodParams = Collections.unmodifiableList(Arrays.asList(methodParams)); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/EntityReceivePotionEffect.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/EntityReceivePotionEffect.java new file mode 100644 index 00000000..259bc40e --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/EntityReceivePotionEffect.java @@ -0,0 +1,31 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.potion.PotionEffect; +import net.minecraftforge.event.entity.living.LivingEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +@Cancelable +public class EntityReceivePotionEffect extends LivingEvent { + public final PotionEffect effect; + public final Object source; + public final Class sourceClass; + public final String methodName; + public final String methodDesc; + public final List methodParams; + + public EntityReceivePotionEffect(EntityLivingBase mcEntity, PotionEffect mcEffect, Object source, Class sourceClass, + String methodName, String methodDesc, Object[] methodParams) { + super(mcEntity); + this.effect = mcEffect; + this.source = source; + this.sourceClass = sourceClass; + this.methodName = methodName; + this.methodDesc = methodDesc; + this.methodParams = Collections.unmodifiableList(Arrays.asList(methodParams)); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/EntitySpawnByFishingHookEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/EntitySpawnByFishingHookEvent.java new file mode 100644 index 00000000..dbea5154 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/EntitySpawnByFishingHookEvent.java @@ -0,0 +1,13 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.projectile.EntityFishHook; +import net.minecraftforge.event.entity.EntityEvent; + +public class EntitySpawnByFishingHookEvent extends EntityEvent { + public final EntityFishHook hook; + public EntitySpawnByFishingHookEvent(Entity entity, EntityFishHook hook) { + super(entity); + this.hook = hook; + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/FishingHookBringEntityEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/FishingHookBringEntityEvent.java new file mode 100644 index 00000000..9bcbc7a6 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/FishingHookBringEntityEvent.java @@ -0,0 +1,16 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.projectile.EntityFishHook; +import net.minecraftforge.event.entity.EntityEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +@Cancelable +public class FishingHookBringEntityEvent extends EntityEvent { + public final EntityFishHook hook; + + public FishingHookBringEntityEvent(Entity entity, EntityFishHook hook) { + super(entity); + this.hook = hook; + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/FishingHookHitEntityEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/FishingHookHitEntityEvent.java new file mode 100644 index 00000000..10e37ef7 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/FishingHookHitEntityEvent.java @@ -0,0 +1,16 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.projectile.EntityFishHook; +import net.minecraftforge.event.entity.EntityEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +@Cancelable +public class FishingHookHitEntityEvent extends EntityEvent { + public final EntityFishHook hook; + + public FishingHookHitEntityEvent(Entity entity, EntityFishHook hook) { + super(entity); + this.hook = hook; + } +} \ No newline at end of file diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PistonMoveEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PistonMoveEvent.java new file mode 100644 index 00000000..b3149e9f --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PistonMoveEvent.java @@ -0,0 +1,31 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import br.com.gamemods.minecity.forge.base.accessors.block.IBlockSnapshot; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.common.util.BlockSnapshot; +import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Cancelable +public class PistonMoveEvent extends BlockEvent { + public final EnumFacing direction; + public final boolean extend; + public final List changes; + public final Object movedBy; + + @SuppressWarnings("unchecked") + public PistonMoveEvent(World world, BlockPos pos, IBlockState state, EnumFacing dir, boolean extend, List changes, Object movedBy) { + super(world, pos, state); + this.direction = dir; + this.extend = extend; + this.changes = Collections.unmodifiableList(new ArrayList(changes)); + this.movedBy = movedBy; + } +} \ No newline at end of file diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PlayerPickupArrowEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PlayerPickupArrowEvent.java new file mode 100644 index 00000000..9fef7a7b --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PlayerPickupArrowEvent.java @@ -0,0 +1,16 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +@Cancelable +public class PlayerPickupArrowEvent extends PlayerEvent { + public final EntityArrow arrow; + + public PlayerPickupArrowEvent(EntityPlayer player, EntityArrow arrow) { + super(player); + this.arrow = arrow; + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PlayerTeleportDragonEggEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PlayerTeleportDragonEggEvent.java new file mode 100644 index 00000000..031fdd91 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PlayerTeleportDragonEggEvent.java @@ -0,0 +1,23 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.common.util.BlockSnapshot; +import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +import java.util.Collections; +import java.util.List; + +@Cancelable +public class PlayerTeleportDragonEggEvent extends BlockEvent { + public final EntityPlayer player; + public final List changes; + public PlayerTeleportDragonEggEvent(EntityPlayer player, World world, BlockPos pos, IBlockState state, List changes) { + super(world, pos, state); + this.player = player; + this.changes = Collections.unmodifiableList(changes); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PostImpactEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PostImpactEvent.java new file mode 100644 index 00000000..7be8fc47 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PostImpactEvent.java @@ -0,0 +1,22 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.entity.Entity; +import net.minecraft.util.math.RayTraceResult; +import net.minecraftforge.common.util.BlockSnapshot; +import net.minecraftforge.event.entity.EntityEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +import java.util.Collections; +import java.util.List; + +@Cancelable +public class PostImpactEvent extends EntityEvent { + public final RayTraceResult traceResult; + public final List changes; + + public PostImpactEvent(Entity entity, RayTraceResult traceResult, List changes) { + super(entity); + this.traceResult = traceResult; + this.changes = Collections.unmodifiableList(changes); + } +} \ No newline at end of file diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PotionApplyEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PotionApplyEvent.java new file mode 100644 index 00000000..6b05c5b8 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PotionApplyEvent.java @@ -0,0 +1,18 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.potion.PotionEffect; +import net.minecraftforge.event.entity.living.LivingEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +@Cancelable +public class PotionApplyEvent extends LivingEvent { + public final PotionEffect effect; + public final Entity potion; + public PotionApplyEvent(EntityLivingBase entity, PotionEffect effect, Entity potion) { + super(entity); + this.effect = effect; + this.potion = potion; + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PreImpactEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PreImpactEvent.java new file mode 100644 index 00000000..752ad026 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/PreImpactEvent.java @@ -0,0 +1,16 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.entity.Entity; +import net.minecraft.util.math.RayTraceResult; +import net.minecraftforge.event.entity.EntityEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +@Cancelable +public class PreImpactEvent extends EntityEvent { + public final RayTraceResult traceResult; + + public PreImpactEvent(Entity entity, RayTraceResult traceResult) { + super(entity); + this.traceResult = traceResult; + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/ProjectileModifyBlockEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/ProjectileModifyBlockEvent.java new file mode 100644 index 00000000..3ec2f828 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/ProjectileModifyBlockEvent.java @@ -0,0 +1,18 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +@Cancelable +public class ProjectileModifyBlockEvent extends BlockEvent { + public final Entity projectile; + + public ProjectileModifyBlockEvent(Entity projectile, World world, BlockPos pos, IBlockState state) { + super(world, pos, state); + this.projectile = projectile; + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/VehicleDamageEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/VehicleDamageEvent.java new file mode 100644 index 00000000..861a17ac --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/VehicleDamageEvent.java @@ -0,0 +1,17 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.entity.Entity; +import net.minecraft.util.DamageSource; +import net.minecraftforge.event.entity.EntityEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +@Cancelable +public class VehicleDamageEvent extends EntityEvent { + public final DamageSource source; + public final float amount; + public VehicleDamageEvent(Entity entity, DamageSource source, float amount) { + super(entity); + this.source = source; + this.amount = amount; + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/XpOrbTargetPlayerEvent.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/XpOrbTargetPlayerEvent.java new file mode 100644 index 00000000..184d8681 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/event/XpOrbTargetPlayerEvent.java @@ -0,0 +1,16 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.event; + +import net.minecraft.entity.item.EntityXPOrb; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.fml.common.eventhandler.Cancelable; + +@Cancelable +public class XpOrbTargetPlayerEvent extends PlayerEvent { + public final EntityXPOrb orb; + + public XpOrbTargetPlayerEvent(EntityPlayer player, EntityXPOrb orb) { + super(player); + this.orb = orb; + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/listeners/ColorTickListener.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/listeners/ColorTickListener.java new file mode 100644 index 00000000..80b956e5 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/listeners/ColorTickListener.java @@ -0,0 +1,28 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.listeners; + +import br.com.gamemods.minecity.forge.base.MineCityForge; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import net.minecraftforge.fml.relauncher.Side; + +public class ColorTickListener { + private MineCityForge forge; + + public ColorTickListener(MineCityForge forge) { + this.forge = forge; + } + + @SubscribeEvent + public void onPlayerTick(TickEvent.PlayerTickEvent event) { + if (event.phase == TickEvent.Phase.END || event.side != Side.SERVER) return; + + forge.player(event.player).tick(); + } + + @SubscribeEvent + public void onServerTick(TickEvent.ServerTickEvent event) { + if (event.phase == TickEvent.Phase.END || event.side != Side.SERVER) return; + + forge.onServerTick(); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/listeners/ColorToolListener.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/listeners/ColorToolListener.java new file mode 100644 index 00000000..4e99e6b0 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/listeners/ColorToolListener.java @@ -0,0 +1,39 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.listeners; + +import br.com.gamemods.minecity.forge.base.MineCityForge; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +public class ColorToolListener extends br.com.gamemods.minecity.forge.base.listeners.ToolListener { + public ColorToolListener(MineCityForge forge) { + super(forge); + } + + @SubscribeEvent + public void onPlayerRightClickBlock(PlayerInteractEvent.RightClickBlock event) { + onPlayerInteract(event, false); + } + + @SubscribeEvent + public void onPlayerLeftClickBlock(PlayerInteractEvent.LeftClickBlock event) { + onPlayerInteract(event, true); + } + + private void onPlayerInteract(PlayerInteractEvent event, boolean left) { + World world = event.getWorld(); + if (world.isRemote) return; + + EntityPlayer player = event.getEntityPlayer(); + BlockPos pos = event.getPos(); + if (onPlayerInteract( + player, player.getHeldItem(EnumHand.MAIN_HAND), + world, pos.getX(), pos.getY(), pos.getZ(), left + )) { + event.setCanceled(true); + } + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/listeners/ColorWorldListener.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/listeners/ColorWorldListener.java new file mode 100644 index 00000000..917a00c2 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/listeners/ColorWorldListener.java @@ -0,0 +1,67 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.listeners; + +import br.com.gamemods.minecity.api.Slow; +import br.com.gamemods.minecity.api.world.ChunkPos; +import br.com.gamemods.minecity.datasource.api.DataSourceException; +import br.com.gamemods.minecity.forge.base.MineCityForge; +import br.com.gamemods.minecity.forge.base.accessors.world.IChunk; +import br.com.gamemods.minecity.forge.base.accessors.world.IWorldServer; +import br.com.gamemods.minecity.structure.ClaimedChunk; +import br.com.gamemods.minecity.structure.Inconsistency; +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraftforge.event.world.ChunkEvent; +import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +public class ColorWorldListener { + private MineCityForge forge; + + public ColorWorldListener(MineCityForge forge) { + this.forge = forge; + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onChunkLoad(ChunkEvent.Load event) throws DataSourceException { + World world = event.getWorld(); + + if (world.isRemote) return; + + Chunk chunk = event.getChunk(); + ChunkPos pos = new ChunkPos(forge.world(world), chunk.x, chunk.z); + pos.instance = chunk; + if (chunk instanceof IChunk) { + ((IChunk) chunk).setMineCityClaim(new ClaimedChunk(Inconsistency.INSTANCE, pos)); + } + + forge.runAsynchronously(() -> { + try { + forge.mineCity.loadChunk(pos); + } catch (Exception e) { + forge.logger.error("Falied to load the chunk: " + pos, e); + } + }); + } + + @Slow + @SubscribeEvent + public void onWorldLoad(WorldEvent.Load event) throws DataSourceException { + World world = event.getWorld(); + + if (world.isRemote) return; + + forge.mineCity.loadNature(forge.world(world)); + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onWorldUnload(WorldEvent.Unload event) throws DataSourceException { + World world = event.getWorld(); + + if (world.isRemote) return; + + if (world instanceof IWorldServer) { + ((IWorldServer) world).setMineCityWorld(null); + } + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/listeners/MineCityColorMod.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/listeners/MineCityColorMod.java new file mode 100644 index 00000000..477041cb --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/listeners/MineCityColorMod.java @@ -0,0 +1,118 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.listeners; + +import br.com.gamemods.minecity.api.MathUtil; +import br.com.gamemods.minecity.api.Slow; +import br.com.gamemods.minecity.api.command.LegacyFormat; +import br.com.gamemods.minecity.datasource.api.DataSourceException; +import br.com.gamemods.minecity.forge.base.MineCityForge; +import br.com.gamemods.minecity.forge.base.command.RootCommand; +import br.com.gamemods.minecity.forge.base.core.ModEnv; +import br.com.gamemods.minecity.forge.mc_1_12_2.MineCityColor; +import br.com.gamemods.minecity.forge.mc_1_12_2.command.ColorTransformer; +import br.com.gamemods.minecity.forge.mc_1_12_2.protection.ColorIndustrialCraftListener; +import br.com.gamemods.minecity.forge.mc_1_12_2.protection.ColorSnapshotHandler; +import br.com.gamemods.minecity.forge.mc_1_12_2.protection.opencomputers.ColorRobotProtections; +import br.com.gamemods.minecity.forge.mc_1_12_2.protection.vanilla.ColorBlockProtections; +import br.com.gamemods.minecity.forge.mc_1_12_2.protection.vanilla.ColorEntityProtections; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.Optional; +import net.minecraftforge.fml.common.event.*; +import net.minecraftforge.fml.relauncher.Side; +import org.xml.sax.SAXException; + +import java.io.IOException; + +@Mod(modid = ModEnv.MOD_ID, name = ModEnv.MOD_ID, version = ModEnv.MOD_VERSION, acceptableRemoteVersions = "*", + acceptedMinecraftVersions = "[1.12.2]", dependencies = "before:opencomputers;before:cofhcore" +) +public class MineCityColorMod { + private MineCityColor forge; + + @Mod.EventHandler + public void onPreInit(FMLPreInitializationEvent event) throws IOException, SAXException { + MathUtil.sin = MathHelper::sin; + MathUtil.cos = MathHelper::cos; + + forge = new MineCityColor(); + forge.logger = event.getModLog(); + forge.selectionTool = Items.WOODEN_HOE; + forge.selectionPallet = selection -> { + selection.cornerA = Blocks.GLOWSTONE.getDefaultState(); + selection.cornerB = Blocks.LIT_REDSTONE_LAMP.getDefaultState(); + selection.corners = Blocks.SEA_LANTERN.getDefaultState(); + selection.linesA = Blocks.GOLD_BLOCK.getDefaultState(); + selection.linesB = Blocks.LAPIS_BLOCK.getDefaultState(); + selection.lines = Blocks.PRISMARINE.getDefaultState(); + selection.extension = Blocks.GLOWSTONE.getDefaultState(); + }; + + LegacyFormat.BLACK.server = TextFormatting.BLACK; + LegacyFormat.DARK_BLUE.server = TextFormatting.DARK_BLUE; + LegacyFormat.DARK_GREEN.server = TextFormatting.DARK_GREEN; + LegacyFormat.DARK_AQUA.server = TextFormatting.DARK_AQUA; + LegacyFormat.DARK_RED.server = TextFormatting.DARK_RED; + LegacyFormat.DARK_PURPLE.server = TextFormatting.DARK_PURPLE; + LegacyFormat.GOLD.server = TextFormatting.GOLD; + LegacyFormat.GRAY.server = TextFormatting.GRAY; + LegacyFormat.DARK_GRAY.server = TextFormatting.DARK_GRAY; + LegacyFormat.BLUE.server = TextFormatting.BLUE; + LegacyFormat.GREEN.server = TextFormatting.GREEN; + LegacyFormat.AQUA.server = TextFormatting.AQUA; + LegacyFormat.RED.server = TextFormatting.RED; + LegacyFormat.LIGHT_PURPLE.server = TextFormatting.LIGHT_PURPLE; + LegacyFormat.YELLOW.server = TextFormatting.YELLOW; + LegacyFormat.WHITE.server = TextFormatting.WHITE; + LegacyFormat.RESET.server = TextFormatting.RESET; + LegacyFormat.MAGIC.server = TextFormatting.OBFUSCATED; + LegacyFormat.BOLD.server = TextFormatting.BOLD; + LegacyFormat.STRIKE.server = TextFormatting.STRIKETHROUGH; + LegacyFormat.UNDERLINE.server = TextFormatting.UNDERLINE; + LegacyFormat.ITALIC.server = TextFormatting.ITALIC; + + forge.onPreInit(new Configuration(event.getSuggestedConfigurationFile()), event.getModLog(), new ColorTransformer()); + MineCityForge.snapshotHandler = new ColorSnapshotHandler(); + MinecraftForge.EVENT_BUS.register(new ColorTickListener(forge)); + MinecraftForge.EVENT_BUS.register(new ColorToolListener(forge)); + MinecraftForge.EVENT_BUS.register(new ColorWorldListener(forge)); + MinecraftForge.EVENT_BUS.register(ModEnv.blockProtections = new ColorBlockProtections(forge)); + MinecraftForge.EVENT_BUS.register(ModEnv.entityProtections = new ColorEntityProtections(forge)); + } + + @Mod.EventHandler + @Optional.Method(modid = "IC2") + public void onPostInitIC(FMLPostInitializationEvent event) { + MinecraftForge.EVENT_BUS.register(new ColorIndustrialCraftListener(forge)); + } + + @Mod.EventHandler + @Optional.Method(modid = "OpenComputers") + public void onPostInitOC(FMLPostInitializationEvent event) { + MinecraftForge.EVENT_BUS.register(new ColorRobotProtections(forge)); + } + + @Slow + @Mod.EventHandler + public void onServerStart(FMLServerAboutToStartEvent event) throws IOException, DataSourceException, SAXException { + forge.onServerAboutToStart(event.getServer(), event.getSide() == Side.CLIENT); + } + + @Mod.EventHandler + public void onServerStart(FMLServerStartingEvent event) { + forge.mineCity.commands.getRootCommands().stream() + .map(name->forge.mineCity.commands.get(name).get()) + .map(r->r.command).distinct() + .forEach(i-> event.registerServerCommand(new RootCommand<>(forge, i))); + } + + @Slow + @Mod.EventHandler + public void onServerStop(FMLServerStoppedEvent event) throws DataSourceException { + forge.onServerStop(); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/ColorIndustrialCraftListener.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/ColorIndustrialCraftListener.java new file mode 100644 index 00000000..780c1552 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/ColorIndustrialCraftListener.java @@ -0,0 +1,55 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.protection; + +import br.com.gamemods.minecity.api.shape.PrecisePoint; +import br.com.gamemods.minecity.forge.base.MineCityForge; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntity; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntityLivingBase; +import br.com.gamemods.minecity.forge.base.accessors.world.IWorldServer; +import br.com.gamemods.minecity.forge.base.protection.industrialcraft.IndustrialCraftProtections; +import ic2.api.event.ExplosionEvent; +import ic2.api.event.LaserEvent; +import net.minecraft.util.EntityDamageSourceIndirect; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +public class ColorIndustrialCraftListener extends IndustrialCraftProtections { + public ColorIndustrialCraftListener(MineCityForge mod) + { + super(mod); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onLaserHitsEntity(LaserEvent.LaserHitsEntityEvent event) { + if (onEntityDamage( + (IEntity) event.hitEntity, + (new EntityDamageSourceIndirect("arrow", event.lasershot, event.owner)).setProjectile(), + event.power, + false + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onLaserHitsBlock(LaserEvent.LaserHitsBlockEvent event) { + if (onLaserHitsBlock( + (IEntity) event.lasershot, + (IWorldServer) event.getWorld(), + event.pos.getX(), event.pos.getY(), event.pos.getZ() + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onExplosionIC2(ExplosionEvent event) { + if (onExplosionIC2( + (IEntity) event.entity, + new PrecisePoint(event.pos.x, event.pos.y, event.pos.z), event.power, + (IEntityLivingBase) event.igniter, + event.rangeLimit, event.radiationRange + )) { + event.setCanceled(true); + } + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/ColorSnapshotHandler.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/ColorSnapshotHandler.java new file mode 100644 index 00000000..7e326b10 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/ColorSnapshotHandler.java @@ -0,0 +1,43 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.protection; + +import br.com.gamemods.minecity.forge.base.accessors.block.IBlockSnapshot; +import br.com.gamemods.minecity.forge.base.protection.SnapshotHandler; +import net.minecraft.block.state.IBlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.common.util.BlockSnapshot; + +import java.util.HashSet; +import java.util.List; + +public class ColorSnapshotHandler implements SnapshotHandler { + @SuppressWarnings("unchecked") + public void restore(List changes) { + HashSet restored = new HashSet<>(); + for (BlockSnapshot snapshot : (List) (List) changes) { + BlockPos snapPos = snapshot.getPos(); + if (restored.contains(snapPos)) continue; + + World world = snapshot.getWorld(); + world.restoringBlockSnapshots = true; + snapshot.restore(true, false); + world.restoringBlockSnapshots = false; + restored.add(snapPos); + } + } + + @SuppressWarnings("unchecked") + public void send(List changes) { + for (BlockSnapshot snapshot : (List) (List) changes) { + int flag = snapshot.getFlag(); + World world = snapshot.getWorld(); + IBlockState oldBlock = snapshot.getReplacedBlock(); + IBlockState newBlock = world.getBlockState(snapshot.getPos()); + //noinspection ConstantConditions + if (newBlock != null && !(newBlock.getBlock().hasTileEntity(newBlock))) + newBlock.getBlock().onBlockAdded(world, snapshot.getPos(), newBlock); + + world.markAndNotifyBlock(snapshot.getPos(), null, oldBlock, newBlock, flag); + } + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/MineCityColorHooks.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/MineCityColorHooks.java new file mode 100644 index 00000000..c1929b30 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/MineCityColorHooks.java @@ -0,0 +1,323 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.protection; + +import br.com.gamemods.minecity.api.shape.Point; +import br.com.gamemods.minecity.forge.base.MineCityForge; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntityLivingBase; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntityPlayerMP; +import br.com.gamemods.minecity.forge.base.accessors.entity.projectile.OnImpact; +import br.com.gamemods.minecity.forge.base.accessors.item.IItem; +import br.com.gamemods.minecity.forge.base.accessors.item.IItemStack; +import br.com.gamemods.minecity.forge.base.accessors.world.IWorldServer; +import br.com.gamemods.minecity.forge.base.core.ModEnv; +import br.com.gamemods.minecity.forge.base.core.Referenced; +import br.com.gamemods.minecity.forge.base.core.transformer.forge.block.BlockDragonEggTransformer; +import br.com.gamemods.minecity.forge.base.core.transformer.forge.block.BlockPistonBaseTransformer; +import br.com.gamemods.minecity.forge.base.core.transformer.forge.block.BlockTNTTransformer; +import br.com.gamemods.minecity.forge.base.core.transformer.forge.block.GrowMonitorTransformer; +import br.com.gamemods.minecity.forge.base.core.transformer.forge.entity.*; +import br.com.gamemods.minecity.forge.base.core.transformer.mod.appeng.IPartHostTransformer; +import br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.BiomeUtilTransformer; +import br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.EntityParticleTransformer; +import br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.TileEntityTeleporterTransformer; +import br.com.gamemods.minecity.forge.base.core.transformer.mod.industrialcraft.TileEntityTerraTransformer; +import br.com.gamemods.minecity.forge.base.core.transformer.mod.opencomputers.AdapterTransformer; +import br.com.gamemods.minecity.forge.base.core.transformer.mod.opencomputers.UpgradeTractorBeamTransformer; +import br.com.gamemods.minecity.forge.mc_1_12_2.ColorUtil; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorEntityPotionTransformer; +import br.com.gamemods.minecity.forge.mc_1_12_2.core.transformer.forge.ColorWorldServerTransformer; +import br.com.gamemods.minecity.forge.mc_1_12_2.event.*; +import net.minecraft.block.BlockDragonEgg; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityXPOrb; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.*; +import net.minecraft.item.ItemStack; +import net.minecraft.pathfinding.PathFinder; +import net.minecraft.pathfinding.PathPoint; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.DamageSource; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3i; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.util.BlockSnapshot; +import net.minecraftforge.fml.common.eventhandler.Event; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Nullable; +import scala.Option; + +import java.util.ArrayList; +import java.util.List; + +@Referenced +public class MineCityColorHooks { + public static volatile Entity spawner; + public static Object pistonMovedBy; + + @Referenced(at = UpgradeTractorBeamTransformer.class) + public static void setPistonMovedBy(Object cause) { + pistonMovedBy = cause; + } + + @Referenced(at = BlockPistonBaseTransformer.class) + public static boolean onPistonMove(boolean ret, Throwable ex, Object blockObj, World world, BlockPos pos, EnumFacing dir, boolean extend) throws Throwable { + world.captureBlockSnapshots = false; + List changes = new ArrayList<>(world.capturedBlockSnapshots); + world.capturedBlockSnapshots.clear(); + Object movedBy = pistonMovedBy; + pistonMovedBy = null; + + try { + IBlockState state = changes.stream() + .filter(snap -> snap.getPos().equals(pos)).map(BlockSnapshot::getReplacedBlock) + .findFirst().orElseGet(() -> world.getBlockState(pos)); + + if (MinecraftForge.EVENT_BUS.post(new PistonMoveEvent(world, pos, state, dir, extend, changes, movedBy))) { + revertChanges(changes); + ret = false; + } else sendUpdates(changes); + } catch(Exception e) { + revertChanges(changes); + throw e; + } + if(ex != null) throw ex; + return ret; + } + @Referenced(at = PathFinderTransformer.class) + public static boolean onPathFind(PathFinder pathFinder, PathPoint point, IBlockAccess access, EntityLiving entity) { + return ModEnv.entityProtections.onPathFind(pathFinder, point, access, entity); + } + + public static void onImpact(Entity entity, RayTraceResult result) { + if(MinecraftForge.EVENT_BUS.post(new PreImpactEvent(entity, result))) { + entity.setDead(); + return; + } + + World worldObj = entity.world; + try { + spawner = entity; + worldObj.captureBlockSnapshots = true; + + ((OnImpact) entity).mineCityOnImpact(result); + + worldObj.captureBlockSnapshots = false; + spawner = null; + + ArrayList changes = new ArrayList<>(worldObj.capturedBlockSnapshots); + worldObj.capturedBlockSnapshots.clear(); + + if(MinecraftForge.EVENT_BUS.post(new PostImpactEvent(entity, result, changes))) + revertChanges(changes); + else + sendUpdates(changes); + } catch(Exception e) { + revertChanges(new ArrayList<>(worldObj.capturedBlockSnapshots)); + throw e; + } finally { + spawner = null; + worldObj.captureBlockSnapshots = false; + worldObj.capturedBlockSnapshots.clear(); + } + } + + @Referenced(at = OnImpactTransformer.class) + public static void onFireBallImpact(EntityFireball fireball, RayTraceResult result) + { + onImpact(fireball, result); + } + + @Referenced(at = OnImpactTransformer.class) + public static void onThrowableImpact(EntityThrowable throwable, RayTraceResult result) { + onImpact(throwable, result); + } + + @Referenced(at = EntityEggTransformer.class) + public static boolean onEggSpawnChicken(EntityEgg egg) { + return MinecraftForge.EVENT_BUS.post(new EggSpawnChickenEvent(egg)); + } + + @SuppressWarnings("unchecked") + private static void revertChanges(List changes) { + MineCityForge.snapshotHandler.restore((List) changes); + } + + @SuppressWarnings("unchecked") + private static void sendUpdates(List changes) { + MineCityForge.snapshotHandler.send((List) changes); + } + + @Contract("!null, _, _, _, _ -> fail") + @Referenced(at = GrowMonitorTransformer.class) + public static void onGrowableGrow(Throwable thrown, Object source, World world, BlockPos pos, IBlockState state) throws Throwable { + world.captureBlockSnapshots = false; + if (world.capturedBlockSnapshots.isEmpty()) { + if(thrown != null) throw thrown; + return; + } + + ArrayList changes = new ArrayList<>(world.capturedBlockSnapshots); + world.capturedBlockSnapshots.clear(); + + if(MinecraftForge.EVENT_BUS.post(new BlockGrowEvent(world, pos, state, source, changes))) revertChanges(changes); + else sendUpdates(changes); + + if(thrown != null) throw thrown; + } + + @Referenced(at = BlockDragonEggTransformer.class) + public static void startCapturingBlocks(World world) { + world.captureBlockSnapshots = true; + } + + @Referenced(at = BlockDragonEggTransformer.class) + public static void onDragonEggTeleport(BlockDragonEgg block, EntityPlayer player, World world, BlockPos pos, IBlockState state) { + world.captureBlockSnapshots = false; + ArrayList changes = new ArrayList<>(world.capturedBlockSnapshots); + world.capturedBlockSnapshots.clear(); + + if (MinecraftForge.EVENT_BUS.post(new PlayerTeleportDragonEggEvent(player, world, pos, state, changes))) { + changes.forEach(snapshot -> { + world.restoringBlockSnapshots = true; + snapshot.restore(true, false); + world.restoringBlockSnapshots = false; + }); + } + } + + @Referenced(at = EntityFishingHookTransformer.class) + public static Entity onFishingHookSpawnEntity(Entity entity, EntityFishHook hook) { + MinecraftForge.EVENT_BUS.post(new EntitySpawnByFishingHookEvent(entity, hook)); + return entity; + } + + @Referenced(at = EntityXPOrbTransformer.class) + public static EntityPlayer onXpOrbTargetPlayer(EntityPlayer player, EntityXPOrb orb) { + if(player == null) return null; + + Event event = new XpOrbTargetPlayerEvent(player, orb); + if(MinecraftForge.EVENT_BUS.post(event)) return null; + else return player; + } + + @Referenced(at = EntityArrowTransformer.class) + public static boolean onPlayerPickupArrow(EntityArrow arrow, EntityPlayer player) { + Event event = new PlayerPickupArrowEvent(player, arrow); + return MinecraftForge.EVENT_BUS.post(event); + } + + @Referenced(at = EntityIgnitionTransformer.class) + public static boolean onIgnite(Entity entity, int fireTicks, @Nullable Object source, Class sourceClass, String method, String desc, Object[] methodParams) { + return MinecraftForge.EVENT_BUS.post(new EntityIgniteEvent( + entity, fireTicks, source, sourceClass, method, desc, methodParams + )); + } + + @Referenced(at = AddPotionEffectObserverTransformer.class) + public static boolean onEntityReceivePotionEffect + (EntityLivingBase mcEntity, PotionEffect mcEffect, Object source, Class sourceClass, + String methodName, String methodDesc, Object[] methodParams) { + return MinecraftForge.EVENT_BUS.post(new EntityReceivePotionEffect( + mcEntity, mcEffect, source, sourceClass, methodName, methodDesc, methodParams + )); + } + + @Referenced(at = EntityEnderCrystalTransformer.class) + public static boolean onEntityDamage(Entity entity, DamageSource source, float amount) { + EntityDamageEvent event = new EntityDamageEvent(entity, source, amount); + return MinecraftForge.EVENT_BUS.post(event); + } + + @Referenced(at = BlockTNTTransformer.class) + public static boolean onArrowIgnite(World world, BlockPos pos, IBlockState state, EntityArrow arrow) { + ProjectileModifyBlockEvent event = new ProjectileModifyBlockEvent(arrow, world, pos, state); + return MinecraftForge.EVENT_BUS.post(event); + } + + @Referenced(at = EntityBoatTransformer.class) + @Referenced(at = EntityMinecartTransformer.class) + public static boolean onVehicleDamage(Entity entity, DamageSource source, float amount) { + VehicleDamageEvent event = new VehicleDamageEvent(entity, source, amount); + return MinecraftForge.EVENT_BUS.post(event); + } + + @Referenced(at = ColorEntityPotionTransformer.class) + public static void onPotionApplyEffect(EntityLivingBase entity, PotionEffect effect, Entity potion) { + PotionApplyEvent event = new PotionApplyEvent(entity, effect, potion); + if(!MinecraftForge.EVENT_BUS.post(event)) entity.addPotionEffect(effect); + } + + @Contract("null, _ -> null") + @Referenced(at = EntityFishingHookTransformer.class) + public static Entity onFishingHookHitEntity(Entity entity, EntityFishHook hook) { + if(entity == null) return null; + + FishingHookHitEntityEvent event = new FishingHookHitEntityEvent(entity, hook); + if(MinecraftForge.EVENT_BUS.post(event)) return null; + else return entity; + } + + @Referenced(at = EntityFishingHookTransformer.class) + public static boolean onFishingHookBringEntity(EntityFishHook hook) { + FishingHookBringEntityEvent event = new FishingHookBringEntityEvent(hook.caughtEntity, hook); + return MinecraftForge.EVENT_BUS.post(event); + } + + @Referenced(at = AdapterTransformer.class) + @Referenced(at = EntityParticleTransformer.class) + @Referenced(at = TileEntityTerraTransformer.class) + @Referenced(at = BiomeUtilTransformer.class) + @Referenced(at = TileEntityTeleporterTransformer.class) + public static Point toPoint(Object obj) { + Vec3i pos = (Vec3i) obj; + return new Point(pos.getX(), pos.getY(), pos.getZ()); + } + + @SuppressWarnings("unchecked") + @Referenced(at = IPartHostTransformer.class) + public static br.com.gamemods.minecity.api.world.BlockPos toPos(Object obj, int x, int y, int z) { + World world; + if (obj instanceof World) world = (World) obj; + else if (obj instanceof Option) world = (World) ((Option)obj).get(); + else throw new UnsupportedOperationException(obj.getClass().toString()); + + return new br.com.gamemods.minecity.api.world.BlockPos(ModEnv.blockProtections.mod.world(world), x, y, z); + } + + @Referenced(at = EntityLivingBaseTransformer.class) + public static boolean onLivingSwing(IItem item, IEntityLivingBase living, IItemStack stack) { + return !((EntityLivingBase) living).world.isRemote && + ModEnv.entityProtections.onLivingSwing(item, living, stack); + } + + @Referenced(at = ColorWorldServerTransformer.class) + public static boolean canMineBlock(World mcWorld, EntityPlayer mcPlayer, BlockPos pos) { + int x = pos.getX(); + int y = pos.getY(); + int z = pos.getZ(); + IWorldServer world = (IWorldServer) mcWorld; + return ModEnv.blockProtections.onBlockBreak(mcPlayer, + world.getIState(x, y, z), + new br.com.gamemods.minecity.api.world.BlockPos(ModEnv.blockProtections.mod.world(world), x, y, z), + false + ); + } + + @Referenced(at = EntityPlayerTransformer.class) + public static boolean canPlayerEdit(EntityPlayer player, BlockPos mcPos, EnumFacing facing, ItemStack stack) { + return !player.world.isRemote && ModEnv.blockProtections.onPlayerCheckEdit( + (IEntityPlayerMP) player, + mcPos.getX(), mcPos.getY(), mcPos.getZ(), + ColorUtil.toDirection(facing), + (IItemStack) (Object) stack + ); + } + + private MineCityColorHooks(){} +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/opencomputers/ColorRobotProtections.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/opencomputers/ColorRobotProtections.java new file mode 100644 index 00000000..09104d64 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/opencomputers/ColorRobotProtections.java @@ -0,0 +1,27 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.protection.opencomputers; + +import br.com.gamemods.minecity.forge.base.protection.opencomputers.IAgent; +import br.com.gamemods.minecity.forge.base.protection.opencomputers.RobotProtections; +import br.com.gamemods.minecity.forge.mc_1_12_2.ColorUtil; +import br.com.gamemods.minecity.forge.mc_1_12_2.MineCityColor; +import li.cil.oc.api.event.RobotMoveEvent; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +public class ColorRobotProtections extends RobotProtections { + private MineCityColor mod; + public ColorRobotProtections(MineCityColor forge) { + super(forge); + mod = forge; + } + + @SubscribeEvent(priority = EventPriority.LOW) + public void onRobotMove(RobotMoveEvent event) { + if (onRobotMove( + (IAgent) event.agent, + ColorUtil.toDirection(event.direction) + )) { + event.setCanceled(true); + } + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/vanilla/ColorBlockProtections.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/vanilla/ColorBlockProtections.java new file mode 100644 index 00000000..b3b0a6a9 --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/vanilla/ColorBlockProtections.java @@ -0,0 +1,198 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.protection.vanilla; + +import br.com.gamemods.minecity.forge.base.accessors.IRayTraceResult; +import br.com.gamemods.minecity.forge.base.accessors.block.IState; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntityPlayerMP; +import br.com.gamemods.minecity.forge.base.accessors.item.IItemStack; +import br.com.gamemods.minecity.forge.base.accessors.world.IWorldServer; +import br.com.gamemods.minecity.forge.base.command.ForgePlayer; +import br.com.gamemods.minecity.forge.base.protection.vanilla.BlockProtections; +import br.com.gamemods.minecity.forge.mc_1_12_2.ColorUtil; +import br.com.gamemods.minecity.forge.mc_1_12_2.MineCityColor; +import br.com.gamemods.minecity.forge.mc_1_12_2.event.BlockGrowEvent; +import br.com.gamemods.minecity.forge.mc_1_12_2.event.PistonMoveEvent; +import br.com.gamemods.minecity.forge.mc_1_12_2.event.PlayerTeleportDragonEggEvent; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.EnumHand; +import net.minecraftforge.event.entity.player.BonemealEvent; +import net.minecraftforge.event.entity.player.FillBucketEvent; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.fml.common.eventhandler.Event; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +import java.util.List; + +public class ColorBlockProtections extends BlockProtections { + private final MineCityColor mod; + + public ColorBlockProtections(MineCityColor mod) { + super(mod); + this.mod = mod; + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onPistonMove(PistonMoveEvent event) { + if (event.getWorld().isRemote) + return; + + if (onPistonMove( + mod.block(event.getWorld(), event.getPos()), + (IState) event.getState(), + ColorUtil.toDirection(event.direction), + event.extend, + event.changes, + event.movedBy + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void onFillBucket(FillBucketEvent event) { + if (event.getWorld().isRemote) return; + + EntityPlayer entityPlayer = event.getEntityPlayer(); + ForgePlayer player = mod.player(entityPlayer); + + if (onFillBucket( + (IEntityPlayerMP) entityPlayer, + (IWorldServer) event.getWorld(), + (IRayTraceResult) event.getTarget(), + (IItemStack) (Object) (player.offHand? entityPlayer.getHeldItemOffhand() : entityPlayer.getHeldItemMainhand()), + player.offHand + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onBoneMeal(BonemealEvent event) { + if (event.getWorld().isRemote) return; + + if (onBoneMeal( + (IEntityPlayerMP) event.getEntityPlayer(), + mod.block(event.getWorld(), event.getPos()), + (IState) event.getBlock() + )) { + event.setCanceled(true); + } + } + + @SuppressWarnings("unchecked") + @SubscribeEvent(priority = EventPriority.HIGH) + public void onBlockGrow(BlockGrowEvent event) { + if(event.getWorld().isRemote) return; + + if(onBlockGrow( + (IState) event.getState(), + mod.block(event.getWorld(), event.getPos()), + (List) event.changes + )) { + event.setCanceled(true); + } + } + + @SuppressWarnings("unchecked") + @SubscribeEvent(priority = EventPriority.HIGH) + public void onDragonEggTeleport(PlayerTeleportDragonEggEvent event) { + if (event.getWorld().isRemote) return; + + if (onDragonEggTeleport( + (IEntityPlayerMP) event.player, + (IState) event.getState(), + mod.block(event.getWorld(), event.getPos()), + (List) event.changes + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onItemRightClick(PlayerInteractEvent.RightClickItem event) { + if (event.getWorld().isRemote) return; + + if (onItemRightClick(event.getEntityPlayer(), event.getItemStack(), event.getHand() == EnumHand.OFF_HAND)) + event.setCanceled(true); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onBlockPlace(BlockEvent.PlaceEvent event) { + if (event.getWorld().isRemote) return; + + EntityPlayer entity = event.getPlayer(); + ForgePlayer player = mod.player(entity); + IItemStack stack = (IItemStack) (Object) (player.offHand? entity.getHeldItemOffhand() : event.getItemInHand()); + if (onBlockPlace(entity, event.getBlockSnapshot(), stack, player.offHand)) + event.setCanceled(true); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onBlockBreak(BlockEvent.BreakEvent event) { + if (event.getWorld().isRemote) return; + + if (onBlockBreak(event.getPlayer(), (IState) event.getState(), mod.block(event.getWorld(), event.getPos()))) + event.setCanceled(true); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onBlockMultiPlace(BlockEvent.MultiPlaceEvent event) { + if (event.getWorld().isRemote) return; + + EntityPlayer entity = event.getPlayer(); + ForgePlayer player = mod.player(entity); + IItemStack stack = (IItemStack) (Object) (player.offHand? entity.getHeldItemOffhand() : event.getItemInHand()); + if (onBlockMultiPlace( + entity, + mod.block(event.getWorld(), event.getPos()), + event.getReplacedBlockSnapshots(), + stack, player.offHand + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onPlayerRightClickBlock(PlayerInteractEvent.RightClickBlock event) { + if (event.getWorld().isRemote) return; + + int result = onPlayerRightClickBlock( + event.getEntityPlayer(), + event.getHand() == EnumHand.OFF_HAND, + event.getItemStack(), + (IState) event.getWorld().getBlockState(event.getPos()), + mod.block(event.getWorld(), event.getPos()), + ColorUtil.toDirection(event.getFace()), + true + ); + + if (result == 3) event.setCanceled(true); + else if (result == 1) { + event.setUseItem(Event.Result.DENY); + event.setCanceled(true); + } + else if (result == 2) event.setUseBlock(Event.Result.DENY); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onPlayerRightClickBlock(PlayerInteractEvent.LeftClickBlock event) { + if(event.getWorld().isRemote) + return; + + int result = onPlayerLeftClickBlock( + (IEntityPlayerMP) event.getEntityPlayer(), + (IState) event.getWorld().getBlockState(event.getPos()), + mod.block(event.getWorld(), event.getPos()), + ColorUtil.toDirection(event.getFace()), + (IItemStack) (Object) event.getItemStack(), + event.getHand() == EnumHand.OFF_HAND + ); + + if (result == 3) event.setCanceled(true); + else if(result == 1) { + event.setUseItem(Event.Result.DENY); + event.setCanceled(true); + } else if (result == 2) event.setUseBlock(Event.Result.DENY); + } +} diff --git a/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/vanilla/ColorEntityProtections.java b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/vanilla/ColorEntityProtections.java new file mode 100644 index 00000000..6a74536d --- /dev/null +++ b/Forge/1.12.2/src/main/java/br/com/gamemods/minecity/forge/mc_1_12_2/protection/vanilla/ColorEntityProtections.java @@ -0,0 +1,439 @@ +package br.com.gamemods.minecity.forge.mc_1_12_2.protection.vanilla; + +import br.com.gamemods.minecity.api.world.BlockPos; +import br.com.gamemods.minecity.forge.base.MineCityForge; +import br.com.gamemods.minecity.forge.base.accessors.IRayTraceResult; +import br.com.gamemods.minecity.forge.base.accessors.block.IState; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntity; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntityLivingBase; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IEntityPlayerMP; +import br.com.gamemods.minecity.forge.base.accessors.entity.base.IPotionEffect; +import br.com.gamemods.minecity.forge.base.accessors.entity.item.IEntityItem; +import br.com.gamemods.minecity.forge.base.accessors.entity.item.IEntityXPOrb; +import br.com.gamemods.minecity.forge.base.accessors.entity.projectile.EntityProjectile; +import br.com.gamemods.minecity.forge.base.accessors.entity.projectile.IEntityArrow; +import br.com.gamemods.minecity.forge.base.accessors.entity.projectile.IEntityFishHook; +import br.com.gamemods.minecity.forge.base.accessors.item.IItemStack; +import br.com.gamemods.minecity.forge.base.accessors.world.IExplosion; +import br.com.gamemods.minecity.forge.base.accessors.world.IWorldServer; +import br.com.gamemods.minecity.forge.base.command.ForgePlayer; +import br.com.gamemods.minecity.forge.base.protection.vanilla.EntityProtections; +import br.com.gamemods.minecity.forge.mc_1_12_2.event.*; +import br.com.gamemods.minecity.forge.mc_1_12_2.protection.MineCityColorHooks; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.EnumHand; +import net.minecraftforge.event.entity.EntityEvent; +import net.minecraftforge.event.entity.EntityJoinWorldEvent; +import net.minecraftforge.event.entity.item.ItemTossEvent; +import net.minecraftforge.event.entity.living.LivingAttackEvent; +import net.minecraftforge.event.entity.living.LivingDropsEvent; +import net.minecraftforge.event.entity.living.LivingExperienceDropEvent; +import net.minecraftforge.event.entity.player.*; +import net.minecraftforge.event.world.ExplosionEvent; +import net.minecraftforge.fml.common.eventhandler.EventPriority; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +import java.util.AbstractList; +import java.util.List; + +public class ColorEntityProtections extends EntityProtections { + public ColorEntityProtections(MineCityForge mod) { + super(mod); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onEntityReceivePotionEffect(EntityReceivePotionEffect event) { + if (event.getEntity().world.isRemote) return; + + if (onEntityReceivePotionEffect( + (IEntityLivingBase) event.getEntityLiving(), + (IPotionEffect) event.effect, + event.source, event.sourceClass, event.methodName, event.methodDesc, event.methodParams + )) + { + event.setCanceled(true); + } + } + + @SuppressWarnings("unchecked") + @SubscribeEvent(priority = EventPriority.HIGH) + public void onExplosion(ExplosionEvent.Detonate event) { + if (event.getWorld().isRemote) return; + + onExplosionDetonate( + (IEntity) MineCityColorHooks.spawner, + (IWorldServer) event.getWorld(), + (IExplosion) event.getExplosion(), + (List) event.getAffectedEntities(), + new AbstractList() { + List base = event.getAffectedBlocks(); + IWorldServer world = (IWorldServer) event.getWorld(); + br.com.gamemods.minecity.api.world.BlockPos last; + + @Override + public br.com.gamemods.minecity.api.world.BlockPos get(int index) { + net.minecraft.util.math.BlockPos cp = base.get(index); + br.com.gamemods.minecity.api.world.BlockPos bp; + if(last == null) + last = bp = new br.com.gamemods.minecity.api.world.BlockPos(mod.world(world), cp.getX(), cp.getY(), cp.getZ()); + else + last = bp = new br.com.gamemods.minecity.api.world.BlockPos(last, cp.getX(), cp.getY(), cp.getZ()); + + bp.getChunk(); + return bp; + } + + @Override + public br.com.gamemods.minecity.api.world.BlockPos set(int index, br.com.gamemods.minecity.api.world.BlockPos pos) { + br.com.gamemods.minecity.api.world.BlockPos prev = get(index); + base.set(index, new net.minecraft.util.math.BlockPos(pos.x, pos.y, pos.z)); + return prev; + } + + @Override + public br.com.gamemods.minecity.api.world.BlockPos remove(int index) { + br.com.gamemods.minecity.api.world.BlockPos removed = get(index); + base.remove(index); + return removed; + } + + @Override + public boolean remove(Object o) { + if (o instanceof br.com.gamemods.minecity.api.world.BlockPos) { + br.com.gamemods.minecity.api.world.BlockPos pos = (br.com.gamemods.minecity.api.world.BlockPos) o; + return base.remove(new net.minecraft.util.math.BlockPos(pos.x, pos.y, pos.z)); + } + return false; + } + + @Override + public void add(int index, br.com.gamemods.minecity.api.world.BlockPos pos) { + base.add(index, new net.minecraft.util.math.BlockPos(pos.x, pos.y, pos.z)); + } + + @Override + public boolean add(br.com.gamemods.minecity.api.world.BlockPos pos) { + return base.add(new net.minecraft.util.math.BlockPos(pos.x, pos.y, pos.z)); + } + + @Override + public int size() { + return base.size(); + } + } + ); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onPreImpact(PreImpactEvent event) { + if (event.getEntity().world.isRemote) return; + + if (onPreImpact( + (IEntity) event.getEntity(), + (IRayTraceResult) event.traceResult + )) { + event.setCanceled(true); + } + } + + @SuppressWarnings("unchecked") + @SubscribeEvent(priority = EventPriority.HIGH) + public void onPostImpact(PostImpactEvent event) { + if (event.getEntity().world.isRemote) return; + + if (onPostImpact( + (IEntity) event.getEntity(), + (IRayTraceResult) event.traceResult, + (List) event.changes + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onEntityEnterWorld(EntityJoinWorldEvent event) { + if(event.getWorld().isRemote) return; + + Entity entity = event.getEntity(); + if (onEntityEnterWorld( + (IEntity) entity, + new br.com.gamemods.minecity.api.world.BlockPos(mod.world(event.getWorld()), (int) entity.posX, (int) entity.posY, (int) entity.posZ), + (IEntity) MineCityColorHooks.spawner + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onEggSpawnChicken(EggSpawnChickenEvent event) { + if (event.getEntity().world.isRemote) return; + + if(onEggSpawnChicken((EntityProjectile) event.getEntity())) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onEntitySpawnByFishingHook(EntitySpawnByFishingHookEvent event) { + if (event.getEntity().world.isRemote) return; + + onEntitySpawnByFishingHook( + (IEntity) event.getEntity(), + (IEntityFishHook) event.hook + ); + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public void onLivingDropsXp(LivingExperienceDropEvent event) { + if (event.getEntityLiving().world.isRemote) return; + + onLivingDropsExp( + (IEntityLivingBase) event.getEntityLiving(), + (IEntityPlayerMP) event.getAttackingPlayer(), + event.getDroppedExperience() + ); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onLivingDrops(LivingDropsEvent event) { + if (event.getEntityLiving().world.isRemote) return; + + onLivingDrops( + (IEntityLivingBase) event.getEntityLiving(), + event.getSource(), + event.getDrops() + ); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onPlayerDrops(PlayerDropsEvent event) { + if (event.getEntityPlayer().world.isRemote) return; + + onPlayerDrops( + (IEntityPlayerMP) event.getEntityPlayer(), + event.getSource(), + event.getDrops() + ); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onItemToss(ItemTossEvent event) { + if (event.getEntity().world.isRemote) return; + + if (onItemToss( + (IEntityPlayerMP) event.getPlayer(), + (IEntityItem) event.getEntityItem() + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onXpOrbTargetPlayerEvent(XpOrbTargetPlayerEvent event) { + if (event.getEntityPlayer().world.isRemote) return; + + if (onXpOrbTargetPlayerEvent( + (IEntityPlayerMP) event.getEntityPlayer(), + (IEntityXPOrb) event.orb + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onPlayerPickupExpEvent(PlayerPickupXpEvent event) { + if (event.getEntity().world.isRemote) return; + + if (onPlayerPickupExpEvent( + (IEntityPlayerMP) event.getEntityPlayer(), + (IEntityXPOrb) event.getOrb() + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onPlayerPickupArrowEvent(PlayerPickupArrowEvent event) { + if (event.arrow.world.isRemote) return; + + if (onPlayerPickupArrowEvent( + (IEntityPlayerMP) event.getEntityPlayer(), + (IEntityArrow) event.arrow + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onProjectileModifyBlock(ProjectileModifyBlockEvent event) { + if (event.getWorld().isRemote) return; + + net.minecraft.util.math.BlockPos pos = event.getPos(); + if (onProjectileModifyBlock( + (IEntity) event.projectile, + (IState) event.getState(), + (IWorldServer) event.getWorld(), + pos.getX(), pos.getY(), pos.getZ() + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onPlayerInteractEntity(PlayerInteractEvent.EntityInteract event) { + if (event.getWorld().isRemote) return; + + if (onPlayerInteractEntity( + (IEntityPlayerMP) event.getEntityPlayer(), + (IEntity) event.getTarget(), + (IItemStack) (Object) event.getItemStack(), + event.getHand() == EnumHand.OFF_HAND + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onEntityConstruct(EntityEvent.EntityConstructing event) { + if (event.getEntity().world.isRemote) return; + + mod.callSpawnListeners((IEntity) event.getEntity()); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onEntityEnterChunk(EntityEvent.EnteringChunk event) { + if (event.getEntity().world.isRemote) return; + + onEntityEnterChunk( + event.getEntity(), + event.getOldChunkX(), + event.getOldChunkZ(), + event.getNewChunkX(), + event.getNewChunkZ() + ); + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onFishingHookHitEntity(FishingHookHitEntityEvent event) { + if (event.hook.world.isRemote) return; + + if (onFishingHookHitEntity( + (IEntity) event.getEntity(), + (EntityProjectile) event.hook + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onFishingHookBringEntity(FishingHookBringEntityEvent event) { + if (event.hook.world.isRemote) return; + + if (onFishingHookBringEntity( + (IEntity) event.getEntity(), + (EntityProjectile) event.hook + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onPotionApply(PotionApplyEvent event) { + if (event.getEntity().world.isRemote) return; + + if (onPotionApply( + (IEntityLivingBase) event.getEntityLiving(), + (IPotionEffect) event.effect, + (IEntity) event.potion + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onPlayerPickupItem(EntityItemPickupEvent event) { + if (event.getEntity().world.isRemote) return; + + if (onPlayerPickupItem( + (IEntityPlayerMP) event.getEntityPlayer(), + (IEntityItem) event.getItem(), + false + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onEntityIgniteEntityEvent(EntityIgniteEvent event) { + if (event.getEntity().world.isRemote) return; + + if (onEntityIgniteEvent( + (IEntity) event.getEntity(), + event.ticks, + event.source, event.sourceClass, + event.sourceMethod, event.sourceMethodDesc, + event.methodParams + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onPlayerAttack(AttackEntityEvent event) { + if (event.getEntity().world.isRemote) return; + + EntityPlayer entity = event.getEntityPlayer(); + ForgePlayer player = mod.player(entity); + if (onPlayerAttack( + (IEntityPlayerMP) entity, + (IEntity) event.getTarget(), + (IItemStack) (Object) (player.offHand? entity.getHeldItemOffhand() : entity.getHeldItemMainhand()), + player.offHand + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onLivingAttack(LivingAttackEvent event) { + if (event.getEntity().world.isRemote) return; + + if (onEntityDamage( + (IEntityLivingBase) event.getEntityLiving(), + event.getSource(), + event.getAmount(), + false + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onVehicleDamage(VehicleDamageEvent event) { + if (event.getEntity().world.isRemote) return; + + if (onEntityDamage( + (IEntity) event.getEntity(), + event.source, + event.amount, + false + )) { + event.setCanceled(true); + } + } + + @SubscribeEvent(priority = EventPriority.HIGH) + public void onEntityDamage(EntityDamageEvent event) { + if (event.getEntity().world.isRemote) return; + + if (onEntityDamage( + (IEntity) event.getEntity(), + event.source, + event.amount, + false + )) { + event.setCanceled(true); + } + } +} diff --git a/Forge/1.7.10/UCS/build.gradle b/Forge/1.7.10/UCS/build.gradle index 8aa987a7..e0b3dd6d 100644 --- a/Forge/1.7.10/UCS/build.gradle +++ b/Forge/1.7.10/UCS/build.gradle @@ -1,9 +1,18 @@ buildscript { repositories { mavenCentral() + jcenter() maven { name = "forge" - url = "http://files.minecraftforge.net/maven" + url = "https://maven.minecraftforge.net/" + } + maven { + name = "forge2" + url = "https://files.minecraftforge.net/maven" + } + maven { + name = "covertdragon" + url = "https://maven.covertdragon.team/repository/internal/" } maven { name = "sonatype" @@ -11,7 +20,9 @@ buildscript { } } dependencies { - classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT' + classpath ('com.anatawa12.forge:ForgeGradle:1.2-1.0.5') { + changing = true + } } } @@ -20,12 +31,12 @@ apply plugin: 'forge' project(':Forge:1.7.10:UCS') { archivesBaseName = "MineCity-Forge-MC1.7.10-UCS" - sourceCompatibility = 1.8 - targetCompatibility = 1.8 + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } minecraft { - version = "1.7.10-10.13.4.1566-1.7.10" + version = "1.7.10-10.13.4.1614-1.7.10" runDir = "run" } @@ -40,10 +51,10 @@ repositories { } dependencies { - compile project(':Forge:1.7.10') - compile "com.github.GameModsBR:UniversalCoinsServer:e0aab5dbb6111b524a00933f5dfa2faddc4ef2e5" - testCompile fileTree(dir: "run/mods", include: ["*.jar"], exclude:["*Assets*"]) - testCompile fileTree(dir: "run/mods/1.7.10", include: ["*.jar"]) + implementation(project(':Forge:1.7.10')) + implementation "com.github.GameModsBR:UniversalCoinsServer:e0aab5dbb6111b524a00933f5dfa2faddc4ef2e5" + testImplementation fileTree(dir: "run/mods", include: ["*.jar"], exclude:["*Assets*"]) + testImplementation fileTree(dir: "run/mods/1.7.10", include: ["*.jar"]) } jar { diff --git a/Forge/1.7.10/build.gradle b/Forge/1.7.10/build.gradle index 138d58a3..2897f5ef 100644 --- a/Forge/1.7.10/build.gradle +++ b/Forge/1.7.10/build.gradle @@ -1,9 +1,18 @@ buildscript { repositories { mavenCentral() + jcenter() maven { name = "forge" - url = "http://files.minecraftforge.net/maven" + url = "https://maven.minecraftforge.net/" + } + maven { + name = "forge2" + url = "https://files.minecraftforge.net/maven" + } + maven { + name = "covertdragon" + url = "https://maven.covertdragon.team/repository/internal/" } maven { name = "sonatype" @@ -11,7 +20,9 @@ buildscript { } } dependencies { - classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT' + classpath ('com.anatawa12.forge:ForgeGradle:1.2-1.0.5') { + changing = true + } } } @@ -20,14 +31,14 @@ apply plugin: 'forge' project(':Forge:1.7.10') { archivesBaseName = "MineCity-Forge-MC1.7.10" - sourceCompatibility = 1.8 - targetCompatibility = 1.8 + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } minecraft { - version = "1.7.10-10.13.4.1566-1.7.10" + version = "1.7.10-10.13.4.1614-1.7.10" runDir = "run" - srgExtra "PK: org/mcstats br/com/gamemods/minecity/forge/mcstats" + // srgExtra "PK: org/mcstats br/com/gamemods/minecity/forge/mcstats" TODO: Reactivate MCStats metrics } configurations { @@ -43,12 +54,12 @@ repositories { dependencies { shade project(':Core') shade project(':Forge:Base') - shade "org.mcstats.forge:metrics:R8-SNAPSHOT" - compile "mysql:mysql-connector-java:5.1.32" - compile "li.cil.oc:OpenComputers:MC1.7.10-1.6.+:api" - compile "net.industrial-craft:industrialcraft-2:2.2.825-experimental:dev" - testCompile fileTree(dir: "run/mods", include: ["*.jar"], exclude:["*Assets*"]) - testCompile fileTree(dir: "run/mods/1.7.10", include: ["*.jar"]) + // shade "org.mcstats.forge:metrics:R8-SNAPSHOT" TODO: Get another nexus for this dependence + implementation "mysql:mysql-connector-java:5.1.32" + implementation "li.cil.oc:OpenComputers:MC1.7.10-1.7.+:api" + implementation "net.industrial-craft:industrialcraft-2:2.2.825-experimental:dev" + testImplementation fileTree(dir: "run/mods", include: ["*.jar"], exclude:["*Assets*"]) + testImplementation fileTree(dir: "run/mods/1.7.10", include: ["*.jar"]) } jar { diff --git a/Forge/1.7.10/src/main/java/br/com/gamemods/minecity/forge/mc_1_7_10/listeners/MineCitySevenMod.java b/Forge/1.7.10/src/main/java/br/com/gamemods/minecity/forge/mc_1_7_10/listeners/MineCitySevenMod.java index 11ed32f5..a72beeb4 100644 --- a/Forge/1.7.10/src/main/java/br/com/gamemods/minecity/forge/mc_1_7_10/listeners/MineCitySevenMod.java +++ b/Forge/1.7.10/src/main/java/br/com/gamemods/minecity/forge/mc_1_7_10/listeners/MineCitySevenMod.java @@ -28,7 +28,7 @@ import net.minecraft.util.MathHelper; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.config.Configuration; -import org.mcstats.Metrics; +//import org.mcstats.Metrics; TODO: Reactivate MCStats metrics import org.xml.sax.SAXException; import java.io.IOException; @@ -103,7 +103,8 @@ public void onPreInit(FMLPreInitializationEvent event) throws IOException, SAXEx @Mod.EventHandler public void onPostInit(FMLPostInitializationEvent event) { - try + // TODO: Reactivate MCStats metrics + /* try { Metrics metrics = new Metrics("MineCity", "forge-1.0-SNAPSHOT"); metrics.start(); @@ -112,6 +113,8 @@ public void onPostInit(FMLPostInitializationEvent event) { forge.logger.warn("MCStats metrics failed to start", e); } + */ + forge.logger.warn("MCStats metrics temporarily disabled."); } @Mod.EventHandler diff --git a/Forge/Base/build.gradle b/Forge/Base/build.gradle index 74d9b608..91dc3052 100644 --- a/Forge/Base/build.gradle +++ b/Forge/Base/build.gradle @@ -2,16 +2,26 @@ // For those who want the bleeding edge buildscript { repositories { + mavenCentral() jcenter() maven { name = "forge" - url = "http://files.minecraftforge.net/maven" + url = "https://maven.minecraftforge.net/" + } + maven { + name = "forge2" + url = "https://files.minecraftforge.net/maven" + } + maven { + name = "sonatype" + url = "https://oss.sonatype.org/content/repositories/snapshots/" } } dependencies { classpath 'net.minecraftforge.gradle:ForgeGradle:2.2-SNAPSHOT' } } + apply plugin: 'net.minecraftforge.gradle.forge' /* @@ -23,12 +33,12 @@ plugins { project(':Forge:Base') { archivesBaseName = "MineCity-Forge-Base" - sourceCompatibility = 1.8 - targetCompatibility = 1.8 + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } minecraft { - version = "1.10.2-12.18.2.2151" + version = "1.10.2-12.18.3.2511" runDir = "run" // the mappings can be changed at any time, and must be in the following format. @@ -36,16 +46,16 @@ minecraft { // stable_# stables are built at the discretion of the MCP team. // Use non-default mappings at your own risk. they may not allways work. // simply re-run your setup task after changing the mappings to update your workspace. - mappings = "snapshot_20160518" + mappings = "snapshot_20161111" // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. } dependencies { - compile project(':Core') - compile(project(':VaultEco')) { + implementation(project(':Core')) + implementation(project(':VaultEco')) { transitive = false } - compile(project(':SpongeEco')) { + implementation(project(':SpongeEco')) { transitive = false } } diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockChorusFlowerTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockChorusFlowerTransformer.java index 60cd4014..942ae395 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockChorusFlowerTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockChorusFlowerTransformer.java @@ -15,6 +15,7 @@ import static org.objectweb.asm.Opcodes.*; @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class BlockChorusFlowerTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockClickExtendsOpenTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockClickExtendsOpenTransformer.java index d64d0d7d..3202bc09 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockClickExtendsOpenTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockClickExtendsOpenTransformer.java @@ -10,6 +10,7 @@ public class BlockClickExtendsOpenTransformer extends InsertInterfaceTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public BlockClickExtendsOpenTransformer() { super("br.com.gamemods.minecity.forge.base.accessors.block.IBlockClickExtendsOpen", Arrays.asList( diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockClickReactorTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockClickReactorTransformer.java index 105d97f9..4c8340d9 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockClickReactorTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockClickReactorTransformer.java @@ -10,6 +10,7 @@ public class BlockClickReactorTransformer extends InsertInterfaceTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public BlockClickReactorTransformer() { super("br.com.gamemods.minecity.forge.base.accessors.block.IBlockClickReactor", Arrays.asList( diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockDragonEggTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockDragonEggTransformer.java index d480c1e8..b6c447f9 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockDragonEggTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockDragonEggTransformer.java @@ -14,6 +14,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class BlockDragonEggTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockModifyExtendsOpenTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockModifyExtendsOpenTransformer.java index 6c036870..9faff7f2 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockModifyExtendsOpenTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockModifyExtendsOpenTransformer.java @@ -10,6 +10,7 @@ public class BlockModifyExtendsOpenTransformer extends InsertInterfaceTransforme { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public BlockModifyExtendsOpenTransformer() { super("br.com.gamemods.minecity.forge.base.accessors.block.IBlockModifyExtendsOpen", Arrays.asList( diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockNoReactExtendsOpenTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockNoReactExtendsOpenTransformer.java index e91d31af..71f8bf19 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockNoReactExtendsOpenTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockNoReactExtendsOpenTransformer.java @@ -10,6 +10,7 @@ public class BlockNoReactExtendsOpenTransformer extends InsertInterfaceTransform { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public BlockNoReactExtendsOpenTransformer() { super("br.com.gamemods.minecity.forge.base.accessors.block.IBlockNoReactionExtendsOpen", Arrays.asList( diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockOpenReactorTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockOpenReactorTransformer.java index 5e98eefc..e319d499 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockOpenReactorTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockOpenReactorTransformer.java @@ -10,6 +10,7 @@ public class BlockOpenReactorTransformer extends InsertInterfaceTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public BlockOpenReactorTransformer() { super("br.com.gamemods.minecity.forge.base.accessors.block.IBlockOpenReactor", Arrays.asList( diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockPistonBaseTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockPistonBaseTransformer.java index c365d347..62ae7c95 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockPistonBaseTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockPistonBaseTransformer.java @@ -15,6 +15,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class BlockPistonBaseTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockSaplingTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockSaplingTransformer.java index c9e57d8b..2ac17aa9 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockSaplingTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockSaplingTransformer.java @@ -15,6 +15,7 @@ import static org.objectweb.asm.Opcodes.*; +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @MethodPatcher diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockStemTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockStemTransformer.java index 66854c38..3d340ce8 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockStemTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockStemTransformer.java @@ -15,6 +15,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class BlockStemTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockTNTTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockTNTTransformer.java index 75885d56..a2f05905 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockTNTTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/BlockTNTTransformer.java @@ -15,6 +15,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class BlockTNTTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/GrowMonitorTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/GrowMonitorTransformer.java index 9e0df5fa..c402bdd5 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/GrowMonitorTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/block/GrowMonitorTransformer.java @@ -62,6 +62,7 @@ public class GrowMonitorTransformer extends BasicTransformer @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public GrowMonitorTransformer() { super(true); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/AddPotionEffectObserverTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/AddPotionEffectObserverTransformer.java index 21e7470e..e5fa5e2e 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/AddPotionEffectObserverTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/AddPotionEffectObserverTransformer.java @@ -20,6 +20,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class AddPotionEffectObserverTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityAreaEffectCloudTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityAreaEffectCloudTransformer.java index 442c86fd..93b65b3c 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityAreaEffectCloudTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityAreaEffectCloudTransformer.java @@ -12,6 +12,7 @@ import java.util.ListIterator; @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class EntityAreaEffectCloudTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityArmorStandTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityArmorStandTransformer.java index ed050397..03a7b432 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityArmorStandTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityArmorStandTransformer.java @@ -15,6 +15,7 @@ * @deprecated Used to fire a custom event but there's a forge event available for the same thing. */ @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @Deprecated @MethodPatcher public class EntityArmorStandTransformer implements IClassTransformer diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityArrowTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityArrowTransformer.java index 2dda98a1..4e43518f 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityArrowTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityArrowTransformer.java @@ -16,6 +16,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class EntityArrowTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityBoatTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityBoatTransformer.java index 215b9af5..5ec3617d 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityBoatTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityBoatTransformer.java @@ -8,6 +8,7 @@ public class EntityBoatTransformer extends InsertDamageHookTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public EntityBoatTransformer() { super("net.minecraft.entity.item.EntityBoat", "onVehicleDamage", "br.com.gamemods.minecity.forge.base.accessors.entity.vehicle.IVehicle"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityEggTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityEggTransformer.java index d7456a06..0290ac82 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityEggTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityEggTransformer.java @@ -13,6 +13,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class EntityEggTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityEnderCrystalTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityEnderCrystalTransformer.java index 8a15d9dc..23295269 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityEnderCrystalTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityEnderCrystalTransformer.java @@ -8,6 +8,7 @@ public class EntityEnderCrystalTransformer extends InsertDamageHookTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public EntityEnderCrystalTransformer() { super("net.minecraft.entity.item.EntityEnderCrystal", "onEntityDamage", "br.com.gamemods.minecity.forge.base.accessors.entity.item.IEntityEndCrystal"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityFishingHookTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityFishingHookTransformer.java index 8fbfd45b..3d77fb23 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityFishingHookTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityFishingHookTransformer.java @@ -17,6 +17,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class EntityFishingHookTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityIgnitionTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityIgnitionTransformer.java index 9bf638f8..992ea8dd 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityIgnitionTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityIgnitionTransformer.java @@ -62,6 +62,7 @@ */ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class EntityIgnitionTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityLivingBaseTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityLivingBaseTransformer.java index 8edcbfd2..b2742c7c 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityLivingBaseTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityLivingBaseTransformer.java @@ -22,6 +22,7 @@ public class EntityLivingBaseTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public EntityLivingBaseTransformer() { super("net.minecraft.entity.EntityLivingBase"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityMinecartTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityMinecartTransformer.java index 3dfec90e..06736f3d 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityMinecartTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityMinecartTransformer.java @@ -8,6 +8,7 @@ public class EntityMinecartTransformer extends InsertDamageHookTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public EntityMinecartTransformer() { super("net.minecraft.entity.item.EntityMinecart", "onVehicleDamage", "br.com.gamemods.minecity.forge.base.accessors.entity.vehicle.IVehicle"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityPlayerTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityPlayerTransformer.java index 830de6cc..f99c37b3 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityPlayerTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityPlayerTransformer.java @@ -15,6 +15,7 @@ public class EntityPlayerTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public EntityPlayerTransformer() { super("net.minecraft.entity.player.EntityPlayer"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityXPOrbTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityXPOrbTransformer.java index c81f72b5..f198a6e6 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityXPOrbTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/EntityXPOrbTransformer.java @@ -14,6 +14,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class EntityXPOrbTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/NodeProcessorTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/NodeProcessorTransformer.java index ebe99649..53327f4f 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/NodeProcessorTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/NodeProcessorTransformer.java @@ -14,6 +14,7 @@ import static org.objectweb.asm.Opcodes.*; @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @Referenced(at = PathFinderTransformer.class) public class NodeProcessorTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/OnImpactTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/OnImpactTransformer.java index bd796e22..3a4ba1dd 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/OnImpactTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/OnImpactTransformer.java @@ -17,6 +17,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class OnImpactTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/PathFinderTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/PathFinderTransformer.java index dc14c9dd..c2a5a9fb 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/PathFinderTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/PathFinderTransformer.java @@ -17,6 +17,7 @@ import static org.objectweb.asm.Opcodes.*; +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @MethodPatcher diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/ProjectileTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/ProjectileTransformer.java index a30a76a0..300058ae 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/ProjectileTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/entity/ProjectileTransformer.java @@ -8,6 +8,7 @@ @Referenced public class ProjectileTransformer extends InsertSetterGetterTransformer { + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") public ProjectileTransformer() diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/item/ItemBucketTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/item/ItemBucketTransformer.java index 906b5128..860af35a 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/item/ItemBucketTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/item/ItemBucketTransformer.java @@ -15,6 +15,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public class ItemBucketTransformer implements IClassTransformer { @Override diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/item/ItemModifyFaceReactorTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/item/ItemModifyFaceReactorTransformer.java index cccb0146..752d591f 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/item/ItemModifyFaceReactorTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/item/ItemModifyFaceReactorTransformer.java @@ -10,6 +10,7 @@ public class ItemModifyFaceReactorTransformer extends InsertInterfaceTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public ItemModifyFaceReactorTransformer() { super("br.com.gamemods.minecity.forge.base.accessors.item.IItemModifyFaceReactor", Arrays.asList( diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/item/ItemTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/item/ItemTransformer.java index 4f28aa4d..6ae97961 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/item/ItemTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/item/ItemTransformer.java @@ -11,6 +11,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public class ItemTransformer extends BasicTransformer { public ItemTransformer() diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/world/ChunkCacheTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/world/ChunkCacheTransformer.java index 073ab067..e766ba5b 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/world/ChunkCacheTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/world/ChunkCacheTransformer.java @@ -13,6 +13,7 @@ import static org.objectweb.asm.Opcodes.*; +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") public class ChunkCacheTransformer implements IClassTransformer diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/world/ChunkTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/world/ChunkTransformer.java index 17785f80..4070258a 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/world/ChunkTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/forge/world/ChunkTransformer.java @@ -29,6 +29,7 @@ public ChunkTransformer(String interfaceClass) } @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public ChunkTransformer() { this("br.com.gamemods.minecity.forge.base.accessors.world.IChunk"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/ModInterfacesTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/ModInterfacesTransformer.java index 51c0a0aa..c8e9f442 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/ModInterfacesTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/ModInterfacesTransformer.java @@ -11,6 +11,7 @@ public class ModInterfacesTransformer extends InsertInterfaceTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public ModInterfacesTransformer() { Map r = new HashMap<>(); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/AEBasePartTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/AEBasePartTransformer.java index ecdd9148..f335a870 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/AEBasePartTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/AEBasePartTransformer.java @@ -12,6 +12,7 @@ public class AEBasePartTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public AEBasePartTransformer() { super("appeng.parts.AEBasePart"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/BlockTinyTNTTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/BlockTinyTNTTransformer.java index 412e7143..dc28015d 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/BlockTinyTNTTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/BlockTinyTNTTransformer.java @@ -14,6 +14,7 @@ public class BlockTinyTNTTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public BlockTinyTNTTransformer() { super("appeng.block.misc.BlockTinyTNT"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/EntityTinyTNTPrimedTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/EntityTinyTNTPrimedTransformer.java index cfd1a2a2..dc79a463 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/EntityTinyTNTPrimedTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/EntityTinyTNTPrimedTransformer.java @@ -15,6 +15,7 @@ public class EntityTinyTNTPrimedTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public EntityTinyTNTPrimedTransformer() { super("appeng.entity.EntityTinyTNTPrimed"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/IPartHostTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/IPartHostTransformer.java index 5c82d4cd..2152dd04 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/IPartHostTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/IPartHostTransformer.java @@ -15,6 +15,7 @@ public class IPartHostTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public IPartHostTransformer() { super("appeng.api.parts.IPartHost"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/PartAnnihilationPaneTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/PartAnnihilationPaneTransformer.java index ed179dd8..ecf55c8a 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/PartAnnihilationPaneTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/PartAnnihilationPaneTransformer.java @@ -14,6 +14,7 @@ public class PartAnnihilationPaneTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public PartAnnihilationPaneTransformer() { super("appeng.parts.automation.PartAnnihilationPlane"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/PartFormationPlaneTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/PartFormationPlaneTransformer.java index 92a90c17..18d1386b 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/PartFormationPlaneTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/PartFormationPlaneTransformer.java @@ -19,6 +19,7 @@ public class PartFormationPlaneTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public PartFormationPlaneTransformer() { super("appeng.parts.automation.PartFormationPlane"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/PartPlacementTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/PartPlacementTransformer.java index 934ab3c3..df3f6559 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/PartPlacementTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/PartPlacementTransformer.java @@ -14,6 +14,7 @@ public class PartPlacementTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public PartPlacementTransformer() { super("appeng.parts.PartPlacement"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/ToolMassCannonTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/ToolMassCannonTransformer.java index bff5f5ee..adab69bf 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/ToolMassCannonTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/ToolMassCannonTransformer.java @@ -18,6 +18,7 @@ public class ToolMassCannonTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public ToolMassCannonTransformer() { super("appeng.items.tools.powered.ToolMassCannon"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/WirelessTerminalGuiObjectTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/WirelessTerminalGuiObjectTransformer.java index b8295d76..bf80866e 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/WirelessTerminalGuiObjectTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/appeng/WirelessTerminalGuiObjectTransformer.java @@ -14,6 +14,7 @@ public class WirelessTerminalGuiObjectTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public WirelessTerminalGuiObjectTransformer() { super("appeng.helpers.WirelessTerminalGuiObject"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/forgemultipart/BlockMultiPartTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/forgemultipart/BlockMultiPartTransformer.java index 8e0e67f4..6bdbfcdc 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/forgemultipart/BlockMultiPartTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/forgemultipart/BlockMultiPartTransformer.java @@ -18,6 +18,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class BlockMultiPartTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/forgemultipart/ButtonPartTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/forgemultipart/ButtonPartTransformer.java index 28592ff7..1a023bd1 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/forgemultipart/ButtonPartTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/forgemultipart/ButtonPartTransformer.java @@ -13,6 +13,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class ButtonPartTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/forgemultipart/EventHandlerTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/forgemultipart/EventHandlerTransformer.java index 4ed0a422..38c00fa5 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/forgemultipart/EventHandlerTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/forgemultipart/EventHandlerTransformer.java @@ -14,6 +14,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class EventHandlerTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/BlockMetalDevicesTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/BlockMetalDevicesTransformer.java index ab875fa0..bb725a78 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/BlockMetalDevicesTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/BlockMetalDevicesTransformer.java @@ -19,6 +19,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class BlockMetalDevicesTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/ChemthrowerEffectTeleportTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/ChemthrowerEffectTeleportTransformer.java index 79720ed9..43575490 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/ChemthrowerEffectTeleportTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/ChemthrowerEffectTeleportTransformer.java @@ -13,6 +13,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class ChemthrowerEffectTeleportTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/ChemthrowerHandlerTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/ChemthrowerHandlerTransformer.java index 05b1dbf7..4f09be21 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/ChemthrowerHandlerTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/ChemthrowerHandlerTransformer.java @@ -17,6 +17,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class ChemthrowerHandlerTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/EntityChemthrowerShotTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/EntityChemthrowerShotTransformer.java index 6a5f1cc5..b7c67aeb 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/EntityChemthrowerShotTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/EntityChemthrowerShotTransformer.java @@ -15,6 +15,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class EntityChemthrowerShotTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/ItemIEToolTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/ItemIEToolTransformer.java index ea46afc2..052072af 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/ItemIEToolTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/ItemIEToolTransformer.java @@ -17,6 +17,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class ItemIEToolTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/TileEntityConveyorSorterTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/TileEntityConveyorSorterTransformer.java index 30f00593..2ec8c2e1 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/TileEntityConveyorSorterTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/TileEntityConveyorSorterTransformer.java @@ -18,6 +18,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class TileEntityConveyorSorterTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/TileEntityFluidPumpTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/TileEntityFluidPumpTransformer.java index f6b3440e..a597d342 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/TileEntityFluidPumpTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveengineering/TileEntityFluidPumpTransformer.java @@ -19,6 +19,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class TileEntityFluidPumpTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveintegration/TileItemRobinTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveintegration/TileItemRobinTransformer.java index 0b019214..b2817247 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveintegration/TileItemRobinTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/immersiveintegration/TileItemRobinTransformer.java @@ -16,6 +16,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class TileItemRobinTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/BiomeUtilTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/BiomeUtilTransformer.java index 08485dd6..1440096b 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/BiomeUtilTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/BiomeUtilTransformer.java @@ -14,6 +14,7 @@ public class BiomeUtilTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public BiomeUtilTransformer() { super("ic2.core.util.BiomeUtil"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/CropCardTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/CropCardTransformer.java index 3eb46123..427f90ce 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/CropCardTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/CropCardTransformer.java @@ -12,6 +12,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public class CropCardTransformer implements IClassTransformer { @Override diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/EntityDynamiteTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/EntityDynamiteTransformer.java index 28730055..1fb54530 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/EntityDynamiteTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/EntityDynamiteTransformer.java @@ -13,6 +13,7 @@ public class EntityDynamiteTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public EntityDynamiteTransformer() { super("ic2.core.block.EntityDynamite"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/EntityIC2ExplosiveTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/EntityIC2ExplosiveTransformer.java index 1a68df67..fa962451 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/EntityIC2ExplosiveTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/EntityIC2ExplosiveTransformer.java @@ -13,6 +13,7 @@ public class EntityIC2ExplosiveTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public EntityIC2ExplosiveTransformer() { super("ic2.core.block.EntityIC2Explosive"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/EntityParticleTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/EntityParticleTransformer.java index c4cc032b..617a173c 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/EntityParticleTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/EntityParticleTransformer.java @@ -21,6 +21,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class EntityParticleTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/ExplosionIC2Transformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/ExplosionIC2Transformer.java index 0a039849..c116960f 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/ExplosionIC2Transformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/ExplosionIC2Transformer.java @@ -18,6 +18,7 @@ public class ExplosionIC2Transformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public ExplosionIC2Transformer() { super("ic2.core.ExplosionIC2"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/ICropTileTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/ICropTileTransformer.java index 878316e6..69bbafde 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/ICropTileTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/ICropTileTransformer.java @@ -15,6 +15,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public class ICropTileTransformer implements IClassTransformer { @Override diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityCropTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityCropTransformer.java index 152294c7..f52bb4f9 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityCropTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityCropTransformer.java @@ -12,6 +12,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class TileEntityCropTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityCropmatronTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityCropmatronTransformer.java index bd2c15f1..a8bcf922 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityCropmatronTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityCropmatronTransformer.java @@ -15,6 +15,7 @@ public class TileEntityCropmatronTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public TileEntityCropmatronTransformer() { super("ic2.core.block.machine.tileentity.TileEntityCropmatron"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityMinerTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityMinerTransformer.java index 5380540c..24c14f43 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityMinerTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityMinerTransformer.java @@ -17,6 +17,7 @@ public class TileEntityMinerTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public TileEntityMinerTransformer() { super(Arrays.asList( diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityRecyclerTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityRecyclerTransformer.java index 9881b3b5..9370918c 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityRecyclerTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityRecyclerTransformer.java @@ -14,6 +14,7 @@ public class TileEntityRecyclerTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public TileEntityRecyclerTransformer() { super("ic2.core.block.machine.tileentity.TileEntityRecycler"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityTeleporterTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityTeleporterTransformer.java index 1f4253de..15fa2a86 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityTeleporterTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityTeleporterTransformer.java @@ -16,6 +16,7 @@ public class TileEntityTeleporterTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public TileEntityTeleporterTransformer() { super("ic2.core.block.machine.tileentity.TileEntityTeleporter"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityTerraTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityTerraTransformer.java index e465757c..630f1f07 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityTerraTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityTerraTransformer.java @@ -20,6 +20,7 @@ public class TileEntityTerraTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public TileEntityTerraTransformer() { super("ic2.core.block.machine.tileentity.TileEntityTerra"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityTeslaTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityTeslaTransformer.java index f585b0fb..96be263f 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityTeslaTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/industrialcraft/TileEntityTeslaTransformer.java @@ -14,6 +14,7 @@ public class TileEntityTeslaTransformer extends BasicTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public TileEntityTeslaTransformer() { super("ic2.core.block.machine.tileentity.TileEntityTesla"); diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/mrcrayfishfurniture/MessageTVServerTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/mrcrayfishfurniture/MessageTVServerTransformer.java index 57f9dfd5..43bff5c4 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/mrcrayfishfurniture/MessageTVServerTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/mrcrayfishfurniture/MessageTVServerTransformer.java @@ -13,6 +13,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class MessageTVServerTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/AdapterTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/AdapterTransformer.java index 639d2ecf..cf4258cd 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/AdapterTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/AdapterTransformer.java @@ -17,6 +17,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class AdapterTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/InventoryTransferDClassTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/InventoryTransferDClassTransformer.java index 371cd368..7589afa4 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/InventoryTransferDClassTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/InventoryTransferDClassTransformer.java @@ -19,6 +19,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class InventoryTransferDClassTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/InventoryWorldControlDClassTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/InventoryWorldControlDClassTransformer.java index 7b83dc1d..e9be0236 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/InventoryWorldControlDClassTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/InventoryWorldControlDClassTransformer.java @@ -16,6 +16,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class InventoryWorldControlDClassTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/InventoryWorldControlMk2DClassTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/InventoryWorldControlMk2DClassTransformer.java index 485b62aa..bc073050 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/InventoryWorldControlMk2DClassTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/InventoryWorldControlMk2DClassTransformer.java @@ -13,6 +13,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class InventoryWorldControlMk2DClassTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/MagnetProviderTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/MagnetProviderTransformer.java index 98997913..b27ff490 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/MagnetProviderTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/MagnetProviderTransformer.java @@ -13,6 +13,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class MagnetProviderTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/PacketHandlerDTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/PacketHandlerDTransformer.java index 5a00fd1f..251f00cd 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/PacketHandlerDTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/PacketHandlerDTransformer.java @@ -16,6 +16,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class PacketHandlerDTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TankWorldControlDClassTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TankWorldControlDClassTransformer.java index c18fcd0c..2f46bcb5 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TankWorldControlDClassTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TankWorldControlDClassTransformer.java @@ -17,6 +17,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class TankWorldControlDClassTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TextBufferTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TextBufferTransformer.java index 4b63011b..6c72e395 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TextBufferTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TextBufferTransformer.java @@ -12,6 +12,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @Referenced public class TextBufferTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TileRobotProxyTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TileRobotProxyTransformer.java index cddd2f63..9c211a17 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TileRobotProxyTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TileRobotProxyTransformer.java @@ -12,6 +12,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public class TileRobotProxyTransformer implements IClassTransformer { @Override diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TransposerTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TransposerTransformer.java index a0bf1700..f2fad92f 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TransposerTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/TransposerTransformer.java @@ -13,6 +13,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class TransposerTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/UpgradeLeashTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/UpgradeLeashTransformer.java index 2c947f4a..261000c8 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/UpgradeLeashTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/UpgradeLeashTransformer.java @@ -13,6 +13,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class UpgradeLeashTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/UpgradePistonTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/UpgradePistonTransformer.java index ad8c4f59..6e96011e 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/UpgradePistonTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/UpgradePistonTransformer.java @@ -16,6 +16,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class UpgradePistonTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/UpgradeTractorBeamTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/UpgradeTractorBeamTransformer.java index b8702cd0..05e8a602 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/UpgradeTractorBeamTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/opencomputers/UpgradeTractorBeamTransformer.java @@ -13,6 +13,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class UpgradeTractorBeamTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/pamharvestcraft/BlockPamSaplingTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/pamharvestcraft/BlockPamSaplingTransformer.java index 9d19f3c6..91aa55b9 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/pamharvestcraft/BlockPamSaplingTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/pamharvestcraft/BlockPamSaplingTransformer.java @@ -12,6 +12,7 @@ import static org.objectweb.asm.Opcodes.*; +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/wrcbe/EntityREPTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/wrcbe/EntityREPTransformer.java index b43330c1..60536b68 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/wrcbe/EntityREPTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/wrcbe/EntityREPTransformer.java @@ -13,6 +13,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class EntityREPTransformer extends InsertSetterGetterTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/wrcbe/JammerPartTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/wrcbe/JammerPartTransformer.java index e008dedf..f1133bab 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/wrcbe/JammerPartTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/wrcbe/JammerPartTransformer.java @@ -15,6 +15,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class JammerPartTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/wrcbe/WirelessBoltTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/wrcbe/WirelessBoltTransformer.java index 8f16b868..2b5e20b5 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/wrcbe/WirelessBoltTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/wrcbe/WirelessBoltTransformer.java @@ -20,6 +20,7 @@ public class WirelessBoltTransformer extends InsertSetterGetterTransformer { @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") + @Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") public WirelessBoltTransformer() { super("codechicken.wirelessredstone.core.WirelessBolt", diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/zettaindustries/BlockSulfurTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/zettaindustries/BlockSulfurTransformer.java index 6b0d1821..63e3a960 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/zettaindustries/BlockSulfurTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/zettaindustries/BlockSulfurTransformer.java @@ -14,6 +14,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class BlockSulfurTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/zettaindustries/QuarryFixerBlockTransformer.java b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/zettaindustries/QuarryFixerBlockTransformer.java index 3632d94c..bffefae1 100644 --- a/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/zettaindustries/QuarryFixerBlockTransformer.java +++ b/Forge/Base/src/main/java/br/com/gamemods/minecity/forge/base/core/transformer/mod/zettaindustries/QuarryFixerBlockTransformer.java @@ -14,6 +14,7 @@ @Referenced("br.com.gamemods.minecity.forge.mc_1_7_10.core.MineCitySevenCoreMod") @Referenced("br.com.gamemods.minecity.forge.mc_1_10_2.core.MineCityFrostCoreMod") +@Referenced("br.com.gamemods.minecity.forge.mc_1_12_2.core.MineCityColorCoreMod") @MethodPatcher public class QuarryFixerBlockTransformer implements IClassTransformer { diff --git a/Forge/Base/src/main/resources/deps.info b/Forge/Base/src/main/resources/deps.info index 5ca5dc51..9190329a 100644 --- a/Forge/Base/src/main/resources/deps.info +++ b/Forge/Base/src/main/resources/deps.info @@ -1,7 +1,7 @@ [ { - "repo": "http://central.maven.org/maven2/mysql/mysql-connector-java/5.1.32", - "file": "mysql-connector-java-5.1.32.jar", + "repo": "https://repo.maven.apache.org/maven2/mysql/mysql-connector-java/6.0.3", + "file": "mysql-connector-java-6.0.3.jar", "class": "com.mysql.jdbc.Driver" } -] \ No newline at end of file +] diff --git a/Forge/Base/src/main/resources/mcmod.info b/Forge/Base/src/main/resources/mcmod.info index 446035c0..fd35dee7 100644 --- a/Forge/Base/src/main/resources/mcmod.info +++ b/Forge/Base/src/main/resources/mcmod.info @@ -7,7 +7,7 @@ "mcversion": "${mcversion}", "url": "", "updateUrl": "", - "authorList": ["joserobjr"], + "authorList": ["joserobjr", "LoboMetalurgico"], "credits": "", "logoFile": "", "screenshots": [], diff --git a/SpongeEco/src/main/java/br/com/gamemods/minecity/sponge/SpongeProxy.java b/SpongeEco/src/main/java/br/com/gamemods/minecity/sponge/SpongeProxy.java index 9fe14231..b257cd8c 100644 --- a/SpongeEco/src/main/java/br/com/gamemods/minecity/sponge/SpongeProxy.java +++ b/SpongeEco/src/main/java/br/com/gamemods/minecity/sponge/SpongeProxy.java @@ -34,7 +34,9 @@ import java.util.Optional; import java.util.Set; -@Plugin(id = "minecitysponge", dependencies = @Dependency(id="minecity"), name = "MineCity-Sponge", +// TODO: HACK, @Dependency doesn't like put forge mods as dependency (when using forge 1.12.2). To fix, set optional as true +@Plugin(id = "minecitysponge", dependencies = @Dependency(id="minecity", optional = true), name = "MineCity-Sponge", + authors = {"joserobjr", "LoboMetalurgico"}, description = "MineCity's module that implements Sponge's Economy and Permission support.") public class SpongeProxy implements EconomyProxy, PermissionProxy { diff --git a/build.gradle b/build.gradle index 9fe3e63d..f12fb60e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,25 +1,35 @@ buildscript { repositories { + mavenCentral() jcenter() } - dependencies { - classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3' - } } +plugins { + id("com.github.johnrengelman.shadow") version "4.0.4" +} + +apply plugin: 'java' + allprojects { - apply plugin: "java" + apply plugin: 'java' + group= "br.com.gamemods.minecity" version = "1.0.A.3-SNAPSHOT" - sourceCompatibility = 1.8 - targetCompatibility = 1.8 + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 tasks.withType(JavaCompile) { options.encoding = 'UTF-8' } -} -subprojects { + subprojects { + apply plugin: 'java' + + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + repositories { mavenCentral() maven { @@ -29,17 +39,13 @@ subprojects { maven { url = 'https://oss.sonatype.org/content/groups/public/' } - maven { - name = 'Plugin Metrics' - url = 'http://repo.mcstats.org/content/repositories/public' - } maven { name = 'sponge' url = 'https://repo.spongepowered.org/maven' } maven { name = 'vault-repo' - url = 'http://nexus.hc.to/content/repositories/pub_releases' + url = 'https://nexus.hc.to/content/repositories/pub_releases' } maven { url = 'https://jitpack.io' @@ -47,29 +53,30 @@ subprojects { } dependencies { - compile "org.jetbrains:annotations:13.0" - testCompile "org.luaj:luaj-jse:3.0.1" - - testCompile "junit:junit:4.12" - testCompile "org.powermock:powermock-module-junit4:1.6.5" - testCompile "org.powermock:powermock-api-mockito:1.6.5" - testCompile project(":UnitTest") - testCompile "mysql:mysql-connector-java:5.1.32" + implementation "org.jetbrains:annotations:13.0" + + testImplementation "org.luaj:luaj-jse:3.0.1" + + testImplementation "junit:junit:4.12" + testImplementation "org.powermock:powermock-module-junit4:1.6.5" + testImplementation "org.powermock:powermock-api-mockito:1.6.5" + testImplementation(project(":UnitTest")) + testImplementation "mysql:mysql-connector-java:5.1.32" } } project(':VaultEco') { dependencies { - compile project(':Core') - compile "net.milkbowl.vault:VaultAPI:1.6" - compile "org.bukkit:bukkit:1.8-R0.1-SNAPSHOT" + implementation(project(':Core')) + implementation "net.milkbowl.vault:VaultAPI:1.6" + implementation "org.bukkit:bukkit:1.8-R0.1-SNAPSHOT" } } project(':SpongeEco') { dependencies { - compile project(':Core') - compile 'org.spongepowered:spongeapi:5.0.0' + implementation(project(':Core')) + implementation 'org.spongepowered:spongeapi:5.0.0' } } @@ -89,8 +96,8 @@ project(':Bukkit') { } //compile files("run/BuildTools/Spigot/Spigot-Server/target/original-spigot-1.10.2-R0.1-SNAPSHOT.jar") //compile files("run/BuildTools/spigot-1.10.2.jar") - compile "org.spigotmc:spigot-api:1.10.2-R0.1-SNAPSHOT" - compile "org.mcstats.bukkit:metrics:R8-SNAPSHOT" + implementation "org.bstats:bstats-bukkit:2.2.1" + implementation "org.spigotmc:spigot-api:1.10.2-R0.1-SNAPSHOT" } jar { @@ -104,13 +111,13 @@ project(':Bukkit') { shadowJar { dependencies { //noinspection GroovyAssignabilityCheck - include(dependency("org.mcstats.bukkit:metrics:R8-SNAPSHOT")) + include(dependency("org.bstats:bstats-bukkit:2.2.1")) include(project(':Core')) } baseName = 'MineCity-Bukkit-MC-1.10.2' - classifier = null - relocate 'org.mcstats', 'br.com.gamemods.minecity.bukkit.mcstats' + // classifier = null + relocate 'org.bstats', 'br.com.gamemods.minecity.bukkit.bstats' } jar.enabled = false @@ -120,6 +127,6 @@ project(':Bukkit') { project(':UnitTest') { dependencies { - compile "org.assertj:assertj-core:3.1.0" + compile "org.assertj:assertj-core:3.11.1" } } diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..784899a6 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,4 @@ +# Sets default memory used for gradle commands. Can be overridden by user or command line properties. +# This is required to provide enough memory for the Minecraft decompilation process. +org.gradle.jvmargs=-Xmx3G +org.gradle.daemon=false diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 30d399d8..7a3265ee 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2dd8be90..ae45383b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Mon Sep 14 12:28:28 PDT 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.7-all.zip diff --git a/gradlew b/gradlew old mode 100755 new mode 100644 index 91a7e269..cccdd3d5 --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh ############################################################################## ## @@ -6,20 +6,38 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,31 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -90,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -114,6 +113,7 @@ fi if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` @@ -154,11 +154,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 8a0b282a..f9553162 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,10 +46,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +59,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line diff --git a/settings.gradle b/settings.gradle index b0ec0510..ea8380bd 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include 'Core', 'Bukkit', 'UnitTest', 'Forge:Base', 'Forge:1.7.10', 'Forge:1.10.2', 'VaultEco', 'Forge:1.7.10:UCS', 'SpongeEco' +include 'Core', 'Bukkit', 'UnitTest', 'Forge:Base', 'Forge:1.7.10', 'Forge:1.10.2', 'VaultEco', 'Forge:1.7.10:UCS', 'SpongeEco','Forge:1.12.2' \ No newline at end of file