de.craftolution.craftoplugin.modules.protection.storage.ProtectionDatabase.java Source code

Java tutorial

Introduction

Here is the source code for de.craftolution.craftoplugin.modules.protection.storage.ProtectionDatabase.java

Source

/*
 * This file is part of CraftoPlugin, licensed under the MIT License (MIT).
 *
 * Copyright (c) 2018 CraftolutionDE <https://craftolution.de>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * Website: http://craftolution.de/
 * Contact: support@craftolution.de
 */
package de.craftolution.craftoplugin.modules.protection.storage;

import com.google.common.collect.Lists;
import de.craftolution.craftodb.Database;
import de.craftolution.craftodb.PreparedQuery;
import de.craftolution.craftodb.QueryResult;
import de.craftolution.craftodb.column.BoolColumn;
import de.craftolution.craftodb.column.EnumColumn;
import de.craftolution.craftodb.column.IntColumn;
import de.craftolution.craftodb.query.Query;
import de.craftolution.craftodb.table.Engine;
import de.craftolution.craftodb.table.IndexType;
import de.craftolution.craftodb.table.Row;
import de.craftolution.craftodb.table.Table;
import de.craftolution.craftolibrary.Check;
import de.craftolution.craftolibrary.Tuple;
import de.craftolution.craftoplugin.core.database.Columns;
import de.craftolution.craftoplugin.modules.protection.ProtectionModule;
import de.craftolution.craftoplugin.modules.protection.loader.ChunkPosition;
import de.craftolution.craftoplugin.modules.protection.protection.BlockProtection;
import de.craftolution.craftoplugin.modules.protection.protection.EntityProtection;
import de.craftolution.craftoplugin.modules.protection.protection.Protection;
import de.craftolution.craftoplugin4.services.database.DatabaseService;
import de.craftolution.craftoplugin4.services.messenger.interfaces.Loggable;
import de.craftolution.craftoplugin4.services.module.Component;
import de.craftolution.craftoplugin4.services.module.exceptions.DisableModuleException;
import org.apache.commons.lang.StringUtils;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * TODO: File description for ProtectionStorage.java
 *
 * @author Fear837, Pingebam
 * @version 1.0
 * @since 30.11.2015 16:26:06
 * @see <a href="https://github.com/Craftolution">Craftolution on Github</a>
 */
public class ProtectionDatabase extends Component implements Loggable {

    private final ProtectionModule module;

    // --- Queries ---

    private PreparedQuery updateEntityProtectionQuery;
    private Lock updateEntityProtectionQueryLock = new ReentrantLock();

    ProtectionDatabase(final ProtectionModule module) {
        this.module = Check.notNull(module, "The module cannot be null!");
    }

    @Override
    public void onEnable() throws DisableModuleException {
        Database db = DatabaseService.instance().get();

        this.updateEntityProtectionQuery = db.prepareQuery(
                "UPDATE `cp_protections` SET `chunk_id` = ? , `loc_x` = ? , `loc_y` = ? , `loc_z` = ? WHERE `id` = ?;");

        if (this.updateEntityProtectionQuery == null) {
            error("updateEntityProtectionQuery is null");
            this.module.disable();
        }

        db.createTable(Table.builder("cp_protections").engine(Engine.InnoDB).addPrimaryId(10)
                .add(IntColumn.name("owner_id"))
                .add(EnumColumn.name("type").values("BLOCK", "ENTITY").defaultValue("BLOCK"))
                .add(IntColumn.name("chunk_id").length(10)).add(Columns.xNew("loc_x")).add(Columns.yNew("loc_y"))
                .add(Columns.zNew("loc_z")).add(IntColumn.name("meta_id").length(8).unsigned().nullable())
                .add(BoolColumn.name("has_whitelist")).add(BoolColumn.name("has_blacklist")).addCreatedAt()
                .index("chunk_id_index", IndexType.INDEX, "chunk_id").build());

        debug("Created table cp_protections");
    }

    @Override
    protected void onDisable() throws Exception {
        this.updateEntityProtectionQuery.close();
    }

    private Protection construct(final Row row) {
        Check.notNull(row, "The row cannot be null!");

        //final int id = row.getInt("id");
        final String type = row.getString("type");
        //final int x = row.getInt("loc_x");
        //final int y = row.getInt("loc_y");
        //final int z = row.getInt("loc_z");
        //final int metaId = row.getInt("meta_id", -1);

        /*// Check if protection with same id is already in cache
        Protection protection = this.module.cache.getById(id).orElse(null);
        if (protection != null && !protection.isGarbage()) {
           warn("construct() called with already loaded protection: " + id);
           return protection;
        }
            
        // Check if duplicate block protection with same location is already in cache
        if (type.equals("BLOCK")) {
           protection = this.module.cache.getByLoc(x, y, z).orElse(null);
            
           if (protection != null && !protection.isGarbage()) {
        warn("construct2() duplicate b protection found for #%s: %s", id, protection);
            
        return protection;
           }
        }
            
        // Check if duplicate entity protection with same entity is already in cache
        if (type.equals("ENTITY")) {
           StoredEntity storedEntity = SharedTablesModule.instance().get().getEntity(metaId).orElse(null);
           if (storedEntity != null) {
        UUID uuid = storedEntity.getUniqueId().get();
        protection = this.module.cache.getByUniqueId(uuid).orElse(null);
            
        if (protection != null && !protection.isGarbage()) {
           warn("construct2() duplicate e protection found for #%s: %s", id, protection);
            
           return protection;
        }
           }
        }
        */

        Protection protection;

        if (type.equals("ENTITY")) {
            // The protection is an entity
            protection = new EntityProtection(this.module, row);
        } else {
            // The protection is only a block
            protection = new BlockProtection(this.module, row);
        }

        return protection;
    }

    Collection<Protection> selectProtsByChunks(final Collection<ChunkPosition> chunks, Database connection) {
        debug("selectProtsByChunks(%s chunks) called!", chunks.size());
        if (chunks.size() == 0) {
            return Collections.emptyList();
        }

        final StringBuilder queryBuilder = new StringBuilder("SELECT * FROM `cp_protections` WHERE `chunk_id` IN(");
        for (ChunkPosition chunk : chunks) {
            queryBuilder.append(chunk.chunkHash).append(", ");
        }
        queryBuilder.delete(queryBuilder.length() - 2, queryBuilder.length()).append(");");

        try (QueryResult res = connection.execute(queryBuilder.toString())) {
            final List<Row> rows = res.getRows();
            final List<Protection> protectionList = Lists.newArrayListWithCapacity(rows.size());

            for (final Row row : rows) {
                Protection protection = this.construct(row);
                protectionList.add(protection);
            }

            debug("selectProtsByChunks(%s): Loaded %s protections!", StringUtils.join(chunks, ", "), rows.size());

            return protectionList;
        }
    }

    public void updateProtection(final EntityProtection protection) {
        if (protection.getId() == Protection.TEMP_ID) {
            return;
        }

        this.updateEntityProtectionQueryLock.lock();
        try {
            this.updateEntityProtectionQuery.setInt(1, protection.getChunkId());
            this.updateEntityProtectionQuery.setInt(2, protection.getX());
            this.updateEntityProtectionQuery.setInt(3, protection.getY());
            this.updateEntityProtectionQuery.setInt(4, protection.getZ());
            this.updateEntityProtectionQuery.setInt(5, protection.getId());

            this.updateEntityProtectionQuery.execute().andClose();
        } finally {
            this.updateEntityProtectionQueryLock.unlock();
        }
    }

}