# Finally a Decent Developer? (jokes, im alright though!)

I'm preva1l, a semi-professional developer specialising in Java & Bukkit plugins!

Here you can find project information and docs!

### My Projects

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Fadah [Free]</strong></td><td>Finally a Decent Auction House</td><td><a href="/files/Wv6JbJySopyyF6HkO33v">/files/Wv6JbJySopyyF6HkO33v</a></td><td></td><td><a href="/pages/3izKrR10Opc7OnVIBvbj">/pages/3izKrR10Opc7OnVIBvbj</a></td></tr><tr><td><strong>Dungeons Terminals [Free]</strong></td><td>MythicDungeons Addon</td><td><a href="/files/j9YgdmkBFTCEsPB46Xcj">/files/j9YgdmkBFTCEsPB46Xcj</a></td><td></td><td><a href="/pages/IPb0oIflWIVeqy10cA1x">/pages/IPb0oIflWIVeqy10cA1x</a></td></tr><tr><td><strong>Fadsb (Soon) [$20 USD]</strong></td><td>Finally a Decent SkyBlock</td><td><a href="/files/mcLKHO0K58RK57xLLwfw">/files/mcLKHO0K58RK57xLLwfw</a></td><td></td><td><a href="/pages/R7MLCQp0laIZlUhX3Nsu">/pages/R7MLCQp0laIZlUhX3Nsu</a></td></tr><tr><td><strong>Fadcs (Soon) [Free]</strong></td><td>Finally a Decent Chest Shop</td><td><a href="/files/FOqxKDU4koxvcUnlRbwc">/files/FOqxKDU4koxvcUnlRbwc</a></td><td></td><td><a href="https://github.com/ProdPreva1l/Docs/blob/master/fadah/api.md">https://github.com/ProdPreva1l/Docs/blob/master/fadah/api.md</a></td></tr></tbody></table>


# Fadah

Finally a Decent Auction House is the fast, modern, advanced and actually good auction house plugin that you have been looking for!

## Looking for help setting up the plugin?

{% content-ref url="/pages/Shw6lawSLQgLwWrhb7vB" %}
[Setup](/fadah/setup)
{% endcontent-ref %}

## Are you a developer? Check out the API docs!

{% content-ref url="/pages/Sma475qoCGidFdOkV7xs" %}
[Developer API](/fadah/api)
{% endcontent-ref %}

## **Plugin Features**

* Item Searching
* Item Filtering
* Infinite & Configurable Categories
* Custom GUI Layouts
* Custom Item Filtered categories
* Multi Server, Folia & ShreddedPaper Support
* Multiple Database Types Supported
* Used & Tested in large production environments
* Listing Tax Permission
* Max Listings Permission
* Transaction Logs
* Listing management (For moderation)
* Migration from other plugins (Only zAuctionHouse & AuctionHouse available)
* Hooks for EcoItems, PlaceholderAPI (Semi)
* Highly Configurable
* Fast Bug Fixes

## **Plugin Requirements**

* Vault
* A Compatible Economy Plugin

### **Optional Requirements**

* A database (MySQL, MariaDB, MongoDB)
* Redis


# Setup

Guides on setting up fadah!

{% hint style="info" %}
Think we are missing something? \
Contribute over on the discord: [https://discord.gg/4KcF7S94HF/](https://discord.gg/4KcF7S94HF)
{% endhint %}

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Connecting A Database</strong></td><td>For help setting up an external database.</td><td></td><td><a href="/files/gTqDBkUuRGJSwXCEQFNu">/files/gTqDBkUuRGJSwXCEQFNu</a></td><td><a href="/pages/XTQU51OBMgwbwRwplocs">/pages/XTQU51OBMgwbwRwplocs</a></td></tr><tr><td><strong>Configuring Multi Server</strong></td><td>For instructions on how to configure Fadah for multiple servers.</td><td></td><td><a href="/files/d8FgljaynQ6op4KACSew">/files/d8FgljaynQ6op4KACSew</a></td><td><a href="/pages/Eb15swFL4OYPXP0L6bo1">/pages/Eb15swFL4OYPXP0L6bo1</a></td></tr><tr><td>Blacklisting items</td><td>Stop items from being listed on the auction house</td><td></td><td><a href="/files/H4MayygZz6oZ6BDD2eOg">/files/H4MayygZz6oZ6BDD2eOg</a></td><td><a href="/pages/3UfkEdU6JcHd3mHYbOY1">/pages/3UfkEdU6JcHd3mHYbOY1</a></td></tr></tbody></table>


# Database

For help setting up an external database.

## Prerequisites (Requirements)

You must have a MySQL, MariaDB or MongoDB server setup.\
The server should be running on the latest version. (Help on finding a host is at the bottom)

## Configuration

Find the `config.yml` file in `plugins/Fadah/` and scroll down the `database` section.

Following the example below.\
Replace `<username>` with your database username. etc...

{% tabs %}
{% tab title="MySQL" %}
{% code title="config.yml" %}

```yaml
database:
  # Supported: SQLITE, MYSQL, MARIADB, MONGO
  type: "MYSQL"
  # Below is not required for SQLITE
  # For MySQL and MariaDB, uri must be a JDBC uri
  uri: "jdbc:mysql://<username>:<password>@<hostname>:<port>/Fadah"
  database: "Fadah"
```

{% endcode %}
{% endtab %}

{% tab title="MariaDB" %}
{% code title="config.yml" %}

```yaml
database:
  # Supported: SQLITE, MYSQL, MARIADB, MONGO
  type: "MARIADB"
  # Below is not required for SQLITE
  # For MySQL and MariaDB, uri must be a JDBC uri
  uri: "jdbc:mariadb://<username>:<password>@<hostname>:<port>/Fadah"
  database: "Fadah"

```

{% endcode %}
{% endtab %}

{% tab title="MongoDB" %}
{% code title="config.yml" %}

```yaml
database:
  # Supported: SQLITE, MYSQL, MARIADB, MONGO
  type: "MONGO"
  # Below is not required for SQLITE
  # For MySQL and MariaDB, uri must be a JDBC uri
  uri: "mongodb://<username>:<password>@<hostname>:<port>/?authSource=admin"
  database: "Fadah"
```

{% endcode %}
{% endtab %}

{% tab title="MongoDB (Atlas)" %}
{% code title="config.yml" %}

```yaml
database:
  # Supported: SQLITE, MYSQL, MARIADB, MONGO
  type: "MONGO"
  # Below is not required for SQLITE
  # For MySQL and MariaDB, uri must be a JDBC uri
  uri: "mongodb+srv://<username>:<password>@<hostname>/?retryWrites=true&w=majority&appName=myapp"
  database: "Fadah"
```

{% endcode %}
{% endtab %}
{% endtabs %}

Once you have completed the configuration, fully restart your Minecraft server and you will now be connected!

## Database Hosting

Most Minecraft hosting plans come with an included MySQL database. You can use this.\
However if you do not have access to said database with your host here are some you can use.

### MySQL

Google Cloud: <https://cloud.google.com/mysql/mysql-hosting>\
Digital Ocean: <https://www.digitalocean.com/products/managed-databases-mysql>

### MariaDB

CloudWays: <https://www.cloudways.com/en/mariadb-hosting.php>\
Amazon Web Services: <https://aws.amazon.com/rds/mariadb/>

### MongoDB

MongoDB Atlas: <https://www.mongodb.com/products/platform/atlas-database>\
(Normal MongoDB is self hosted only)


# Multi Server

For instructions on how to configure Fadah for multiple servers.

### Pre-Requisites

You must first have an [external database setup](/fadah/setup/database). You must also have a Redis server. (Or a server that uses the Redis protocol)\
This should be running the latest version.

### Configuration

Find the configuration section at the bottom of the config.yml file and configure it as follows.

The configuration (and database) MUST be identical for all connected servers.

{% code title="plugins/Fadah/config.yml" %}

```yaml
broker:
  enabled: true
  type: REDIS
  host: your-redis-server-ip
  port: your-redis-server-port
  password: your-redis-server-password
  channel: fadah:cache
```

{% endcode %}

Once you have completed the configuration on all of your servers, fully restart your servers and you will now be connected!

### Redis Server Hosting

Refer to this amazing guide by William!\
<https://william278.net/docs/website/redis-hosts>


# Category Filtering & Blacklists

How to setup categories and blacklisted items

Category filters and blacklists use the same system internally.\
Strings check for booleans (true or false) and are parsed using javascript.\
You can use any javascript methods that are for comparison and you can use the following placeholders:

`%lore%` `%name%` `%amount%` `%material%`

Some examples would be:\
`%lore%.includes("Mythical Item")` would match true if the items lore has "Mythical Item" anywhere in it.\
You can also use logical operators (such as && and ||) for example: `%name% == "Custom Item" && %amount% >= 3` would match if the name is "Custom Item" and there is 3 items in the stack.

### Additional Hooks

Some hooks are also added for more filtering options.\
Currently there is; EcoItems.

#### EcoItems

`%ecoitems_id%`&#x20;


# Commands & Permissions

## Commands

| Command               | Permission              | Command Description                                  |
| --------------------- | ----------------------- | ---------------------------------------------------- |
| /ah                   | `fadah.use`             | Opens Auction House menu.                            |
| /ah help              | `fadah.help`            | Displays a help message with main commands.          |
| /ah sell \<price>     | `fadah.use`             | Opens Auction House sell menu.                       |
| /ah toggle            | `fadah.toggle-status`   | Enables/Disables Fadah.                              |
| /ah reload            | `fadah.reload`          | Reloads the plugin.                                  |
| /ah profile \[player] | `fadah.profile`         | Open yours or another players profile.               |
| /ah expired \[player] | `fadah.expired-items`   | Open yours or another players expired auctions.      |
| /ah redeem \[player]  | `fadah.collection-box`  | Open yours or another players collection box.        |
| /ah active \[player]  | `fadah.active-listings` | Open yours or another players active listings.       |
| /ah history \[player] | `fadah.history`         | Open yours or another players Auction House history. |

## Permissions

{% hint style="warning" %}
Permissions that have an \[amount] are currently not weighted. \
The plugin will use the highest number.
{% endhint %}

| Permission                     | Permission Description                                                                  |
| ------------------------------ | --------------------------------------------------------------------------------------- |
| `fadah.max-listings.[amount]`  | How many items the user can list on the auction house at any one time.                  |
| `fadah.listing-tax.[amount]`   | The percent a user should be taxed from the products price. (Do not include the % sign) |
| `fadah.advert-price.[amount]`  | How much an advert should cost for the player.                                          |
| `fadah.manage.profile`         | Allows the user to manage other peoples profiles.                                       |
| `fadah.manage.active-listings` | Allows the user to manage other peoples listings.                                       |
| `fadah.manage.expired-items`   | Allows the user to manage other peoples expired items.                                  |
| `fadah.manage.collection-box`  | Allows the user to manage other peoples collection box.                                 |


# Developer API

The Developer API for Fadah is very extensive, these docs aim to cover it fully!

## Useful Resources

JavaDocs: <https://repo.preva1l.info/javadoc/releases/info/preva1l/fadah/API/latest>\
Support Server: [https://discord.gg/4KcF7S94HF/](https://discord.gg/4KcF7S94HF)

## Getting Started

To get started with the API you must add it to your Maven / Gradle Project.

Replace LATEST-VERSION with the version found below.

<figure><img src="https://badge.fury.io/gh/Finally-A-Decent%2FFadah.svg" alt=""><figcaption></figcaption></figure>

{% tabs %}
{% tab title="Maven" %}

```xml
<repositories>
    <repository>
        <id>FinallyADecent</id>
        <url>https://repo.preva1l.info/releases/</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>info.preva1l.fadah</groupId>
        <artifactId>API</artifactId>
        <version>LATEST-VERSION</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
```

{% endtab %}

{% tab title="Gradle (Groovy)" %}

```gradle
repositories {
    maven { url 'https://repo.preva1l.info/releases' }
}

dependencies {
    compileOnly 'info.preva1l.fadah:API:LATEST-VERSION'
}
```

{% endtab %}

{% tab title="Gradle (Kotlin)" %}

```gradle
repositories {
    maven("https://repo.preva1l.info/releases/")
}

dependencies {
    compileOnly("info.preva1l.fadah:API:LATEST-VERSION")
}
```

{% endtab %}
{% endtabs %}

### Depending on Fadah

{% code title="plugin.yml" %}

```yaml
name: "FadahAPIExample"
version: "1.0"
api-version: "1.20"
main: me.developer.FadahAPIExample

depend:
  - "Fadah"
```

{% endcode %}

## Next Steps

{% content-ref url="/pages/vHE0rYhF0nFFYauMQ2nr" %}
[Accessing & Using Data](/fadah/api/accessing-data)
{% endcontent-ref %}

{% content-ref url="/pages/up0TGI4PoVLSJ9kj3YH3" %}
[Events](/fadah/api/events)
{% endcontent-ref %}

{% content-ref url="/pages/99HdntY8Gb1O4aZPO0zD" %}
[Adding a Economy Hook](/fadah/api/economy)
{% endcontent-ref %}


# Accessing & Using Data

Access data  using the API.

## Getting Started

You will first need to get the instance of the Fadah API.

<pre class="language-java"><code class="lang-java">import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import info.preva1l.fadah.api.AuctionHouseAPI;

public final class FadahAPIExample extends JavaPlugin {
    private AuctionHouseAPI fadahApi;

    @Override
    public void onEnable() {
<strong>        if (Bukkit.getPluginManager().getPlugin("Fadah") != null) {
</strong><strong>            fadahApi = AuctionHouseAPI.getInstance();
</strong>        }
    }
}
</code></pre>

## Listing Data

Now that you have an instance of the Fadah API we can now access the ListingManager class

```java
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.Material
import org.bukkit.inventory.ItemStack
import org.bukkit.plugin.java.JavaPlugin;

import info.preva1l.fadah.api.AuctionHouseAPI;
import info.preva1l.fadah.api.managers.ListingManager;
import info.preva1l.fadah.records.listing.Listing;
import info.preva1l.fadah.records.listing.ListingBuilder;
import info.preva1l.fadah.currency.CurrencyRegistry;

import java.util.List;

public final class FadahAPIExample extends JavaPlugin {
    @Override
    public void onEnable() {
        ListingManager manager = AuctionHouseAPI.getInstance().listingManager();
        
        // Getting listings
        List<Listing> listings = manager.all();
        
        // Creating a listing
        Currency currency = CurrencyRegistry.getAll().getFirst();
        Player player = Bukkit.getPlayer("Preva1l");
        ItemStack item = player.getInventory().getItemInMainHand();
        player.getInventory().setItemInMainHand(new ItemStack(Material.AIR));
        manager.listingBuilder(player)
                .price(4_500_000) // 4.5 Million
                .tax(3.5) // This is a percentage, so 3.5%, the default is 0%
                .currency(currency) // By default this is the same as what we have it
                .length(2 * 60 * 60 * 1000) // 2 Hours, this is also a default value
                .itemStack(item)
                .biddable(false) // this is false by default, bidding is still W.I.P.
                .toPost() // theres alot more options you can change in this section
                .postAdvert(true)
                .buildAndSubmit().thenAccept(result -> {
                    if (!result.successful()) {
                        player.sendMessage(
                            "Failed to post listing! " + result.message()
                        );
                        player.getInventory().setItemInMainHand(item);
                        return;
                    }
                    
                    player.sendMessage("Listing Posted!");
                });
    }
}
```


# Events

Listen for Events via the API.

## Getting started

First setup your listeners.

<pre class="language-java" data-title="FadahAPIExample.java"><code class="lang-java">import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.Bukkit;
<strong>
</strong><strong>public final class FadahAPIExample extends JavaPlugin {
</strong>
    @Override
    public void onEnable() {
        if (Bukkit.getPluginManager().getPlugin("Fadah") != null) {
            Bukkit.getPluginManager().registerEvents(new FadahAPIExampleListener(), this);
        }
    }
}
</code></pre>

{% code title="FadahAPIExampleListener.java" %}

```java
import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;

public class FadahAPIExampleListener implements Listener {
    // Add listeners here.
}
```

{% endcode %}

Now you can add your listeners!

## ListingCreateEvent

This event is cancellable and accepts a reason to show the player.

{% code title="FadahAPIExampleListener.java" %}

```java
public class FadahAPIExampleListener implements Listener {
    @EventHandler
    public void onListingStart(ListingCreateEvent e) {
        if (e.getPlayer().getName().equalsIgnoreCase("IhateFadah")) {
            e.setCancelReason("Nuh uh!");
            e.setCancelled(true);
        }
    }
}
```

{% endcode %}

## ListingEndEvent

<pre class="language-java" data-title="FadahAPIExampleListener.java"><code class="lang-java"><strong>public class FadahAPIExampleListener implements Listener {
</strong>    @EventHandler
    public void onListingEnd(ListingEndEvent e) {
        if (e.getReason() == ListingEndReason.CANCELLED_ADMIN) {
            Player player = Bukkit.getPlayer(e.getListing().getOwner());
            if (player == null) return;
            player.sendMessage("An admin has cancelled your listing!");
        }
    }
}
</code></pre>

## ListingPurchaseEvent

{% code title="FadahAPIExampleListener.java" %}

```java
public class FadahAPIExampleListener implements Listener {
    @EventHandler
    public void onListingPurchase(ListingPurchaseEvent e) {
        Player player = Bukkit.getPlayer(e.getListing().getOwner());
        if (player == null) return;
        player.sendMessage("%s has purchased your listing!"
                .formatted(e.getBuyer().getName()));
    }
}
```

{% endcode %}


# Adding a Economy Hook

This page will provide you with the information to add an economy hook to fadah!

### Adding a Single Currency

```java
public class MyCustomCurrency implements Currency {
    private MyPluginsAPI api;
    
    @Override
    public String getId() {
        return "my_currency";
    }
    
    @Override
    public String getRequiredPlugin() {
        return "MyPlugin";
    }
    
    @Override
    public String getName() {
        return "Super Money";
    }

    @Override
    public void withdraw(OfflinePlayer player, double amountToTake) {
        api.take(player, amountToTake);
    }

    @Override
    public void add(OfflinePlayer player, double amountToAdd) {
        api.give(player, amountToAdd);
    }

    @Override
    public double getBalance(OfflinePlayer player) {
        return api.get(player);
    }

    @Override
    public boolean preloadChecks() {
        api = MyPluginsAPI.getInstance()
        return api != null;
    }
}

```

### Adding a Multi Currency

<pre class="language-java"><code class="lang-java">public class MyMultiCurrency implements MultiCurrency {
    private final List&#x3C;Currency> currencies = new ArrayList&#x3C;>();
    private MyPluginsAPI api;
    
<strong>    @Override
</strong>    public String getId() {
        return "my_plugin";
    }
    
    @Override
    public String getRequiredPlugin() {
        return "MyPlugin";
    }
    
    @Override
    public List&#x3C;Currency> getCurrencies() {
        return currencies;
    }

    @Override
    public boolean preloadChecks() {
        api = MyPluginsAPI.getInstance()
        if (api == null) return false;

        for (String economy : List.of("gems", "tokens")) {
            Currency subCur = new SubCurrency(
                id + "_" + economy,
                economy,
                requiredPlugin,
                (player, amount) -> api.take(p.getUniqueId(), economy, amount),
                (player, amount) -> api.give(p.getUniqueId(), economy, amount),
                player -> api.get(player.getUniqueId(), economy),
                v -> {
                    if (!api.currencyExists(economy)) {
                        System.out.println("-------------------------------------");
                        System.out.println("Cannot enable coins engine currency!");
                        System.out.println("No currency with name: " + eco.economy());
                        System.out.println("-------------------------------------");
                        return false;
                    }
                    return true;
                }
            );
            currencies.add(subCur);
        }
        return true;
    }
}

</code></pre>

### Registering your currency

```java
CurrencyRegistry.register(new MyCustomCurrency());
CurrencyRegistry.register(new MyMultiCurrency());
```


# Dungeons Terminals

DungeonsTerminals is an extension to MythicDungeons (2.0.0) to add Hypixel-esque terminals!

How to setup

{% embed url="<https://youtu.be/6lxFH2XsJNM>" %}


# Fadsb

Finally a Decent SkyBlock

Docs Coming Soon!


