# Overview

Documentation overview

* [Map-Ads](/map-ads/map-ads-overview)


# Map-Ads Overview

Map-Ads is an advertising plugin that utilizes maps. Players can rent ad-screens for a specified amount of time and submit their own images which will then be displayed. Staff can review these images before they go live.

Please join the [Discord server](https://discord.gg/brb9eYp57E) if you need help or if you want to report a bug / file a feature request. (Please note that I will only give support to purchasers of the plugin. You can still file bug reports / feature requests without purchasing the plugin)

### Contents

* [Installation and Configuration](/map-ads/installation-and-configuration)
  * [Help book configuration](/map-ads/installation-and-configuration/help-book-configuration)
  * [Language file](/map-ads/installation-and-configuration/language-file)
* [Setup](/map-ads/setup)
* [Developer API](/map-ads/developer-api)
* [FAQ](/map-ads/faq)


# Installation and configuration

## How to install the Map-Ads plugin

1. Download the 'map-ads' plugin from SpigotMC.org
2. Download the 'maps' plugin from GitHub
   1. For 1.1.4 and below download [maps v1.0.6](https://github.com/cerus/maps/releases/download/1.0.6/maps.jar)
   2. For 1.2.0 - 1.2.11 download [maps v2](https://github.com/cerus/maps/releases/download/2.0.2/maps-plugin.jar)
   3. For 1.2.12 and up download [maps v3](https://l.cerus.dev/maps-latest)
3. Drop both plugins into your plugins folder
4. Restart the server

{% hint style="warning" %}
Note: You will need at least Java 16 and Minecraft 1.16.5 to run this plugin.
{% endhint %}

## Configuring Map-Ads

This is the default config:

```yaml
image-storage:
  type: "SQLite" # SQLite, MySQL
  mysql:
    host: "127.0.0.1"
    port: 3306
    db: "mapads"
    user: "mapads_user"
    pass: "secure_password_123"
  sqlite:
    db-name: "images.db"
advert-storage:
  type: "SQLite" # SQLite, MySQL
  mysql:
    host: "127.0.0.1"
    port: 3306
    db: "mapads"
    user: "mapads_user"
    pass: "secure_password_123"
  sqlite:
    db-name: "adverts.db"

images:
  max-size: 5242880
  url-whitelist:
    - "imgur.com"
    - "*.imgur.com"
ads:
  min-ad-minutes: 10
  max-ad-minutes: 120
  step: 5
  price-per-minute: 1000.0

enable-advanced-optimization-algorithm: false
send-update-message: true
disable-default-command: false
only-show-groups: false
deduct-each-screen-in-group: false
record-transitions: false
override-economy: ""
despawn-range: 64

default-images: { }
```

### image-storage and advert-storage

Here you can choose where you want to store the images/adverts. The supported storage types are MySQL and SQLite. Simply adjust the section of the storage type you want to use and change the 'type' field.

### images

This section contains general settings for images. You can specify the maximum size and add/remove websites from the whitelist. See footnote 1 for examples on how the whitelist wildcards work.\
The maximum size is measured in bytes (the default equates to exactly 5 MB). 1 KB = 1024 bytes and 1 MB = 1024 KB.

~~You can also enable / disable the color cache feature. The color cache will reduce the time that image converting takes by *a lot*, but it will also take up \~16 MB of memory in return. Use this if you have enough memory.~~

{% hint style="danger" %}
Important security note: Only add **trusted** sites to the whitelist because players will try to exploit this functionality.
{% endhint %}

{% hint style="info" %}
The color cache has been removed. A more efficient memory cache is now used instead.
{% endhint %}

> ### ads

This controls general settings for advertisements.\
`min-ad-minutes` specifies the minimum amount of minutes for an advertisement.\
`max-ad-minutes` specifies the maximum amount of minutes for an advertisement.\
`step` specifies the minute increments when purchasing an ad.\
`price-per-minute` specifies the price for each minute. The total price will be calculated like this: `selected_minutes * price_per_minute`

![This is what the default settings (min = 10, max = 120, step = 5) look like ingame](/files/-MlRxgT5Ns3HduyISeqc)

### ~~enable-advanced-optimization-algorithm~~

~~Enables (or disables) the~~ [~~Advanced Content Change Algorithm~~](https://github.com/cerus/maps/wiki/Concepts:-The-Advanced-Content-Change-Algorithm)~~. This algorithm is an optimization method that (in theory) reduces bandwidth and CPU usage by essentially doubling the memory usage.~~

{% hint style="info" %}
This algorithm has been removed in maps v2. A better algorithm is now used.
{% endhint %}

### disable-default-command

Disables the `/mapads` command which shows the current version, author and website of the plugin.

### only-show-groups

If enabled this will only show screen groups in the screen selector when creating an ad.

### deduct-each-screen-in-group

Will deduct one minute from the adverts lifetime for each screen in the rented screen group.&#x20;

Example: Group 'abc' has three screens. I rent the 'abc' group for a 15 minute advertisement. If this option is enabled each time my ad is shown on each of the screens one minute is deducted from the remaining minutes. If this option is disabled only the first screen in the group will deduct one minute from the remaining minutes.

### record-transitions

If set to `true` the plugin will record transitions. This has the potential to save lots of processing power because the plugin only needs to compute the transition once for each image pair and can then play back the recordings.

{% hint style="warning" %}
The transition recording feature is experimental and disabled by default. Please report bugs on the Discord server.
{% endhint %}

### override-economy

This allows you to force Map-Ads to use a specific economy plugin. Please see the "[Economy plugins](/map-ads/installation-and-configuration/economy-plugins)" page for a list of supported economy plugins.

### default-images

Will be interpreted and changed by the plugin. Do not change anything here if you don't know what you're doing.

### despawn-range

This is the view distance for ad-screens.

#### Footnote 1

Lets say your whitelist contains "imgur.com" and "\*.imgur.com". The following urls would be accepted:

* <https://imgur.com/something>
* <https://imgur.com>
* <https://i.imgur.com/abcdef.png>
* <https://beans.imgur.com/>

The following urls would **not** be accepted:

* <https://abc.def.imgur.com/>
* <https://imgur.xyz>
* <https://google.com>


# Help book configuration

The help book is a configurable written book that aims to explain the advertising process to players. You can use [MiniMessage](https://docs.adventure.kyori.net/minimessage#format) to style the book.

The default help book config (`plugins/map-ads/helpbook.yml`) looks like this: ([alternative link](https://paste.goose.rodeo/3mrWZk))

```yaml
title: "Map-Ads Help"
author: "Cerus"
pages:
  '1':
    - "    <gradient:#1D746A:#CD9B31><b>Map-Ads Help</b></gradient>"
    - ""
    - "<gradient:#3390C8:#58B9F3><b>Contents</b></gradient>"
    - " 1. <hover:show_text:'<color:gray><i>Jump to \"Advertising\"</i></color>'><click:change_page:2>Advertising</click></hover>"
    - "  1.1. <hover:show_text:'<color:gray><i>Jump to \"The screen\"</i></color>'><click:change_page:3>The screen</click></hover>"
    - "  1.2. <hover:show_text:'<color:gray><i>Jump to \"Images\"</i></color>'><click:change_page:4>Images</click></hover>"
    - "  1.3. <hover:show_text:'<color:gray><i>Jump to \"Image dithering\"</i></color>'><click:change_page:5>Image dithering</click></hover>"
    - "  1.4. <hover:show_text:'<color:gray><i>Jump to \"Time\"</i></color>'><click:change_page:6>Time</click></hover>"
    - "  1.5. <hover:show_text:'<color:gray><i>Jump to \"Confirming\"</i></color>'><click:change_page:7>Confirming</click></hover>"
    - " 2. <hover:show_text:'<color:gray><i>Jump to \"Previewing\"</i></color>'><click:change_page:8>Previewing</click></hover>"
  '2':
    - "<gradient:#0F4E73:#719FBA><b>Advertising</b></gradient>"
    - ""
    - "To open the advertising GUI, type <color:gold><b><hover:show_text:'<gray><i>Click to run command'><click:run_command:/mapads advertise>/mapads advertise</click></hover></b></color>."
    - "Choose an ad-screen, submit your image, set the amount of minutes you want to purchase and that's it!"
  '3':
    - "<gradient:#0F4E73:#719FBA><b>Advertising</b></gradient>"
    - "<gradient:#3390C8:#58B9F3><b>The screen</b></gradient>"
    - ""
    - "In order to advertise you will have to choose an ad-screen by clicking the map item in the upper left corner. Ad-screens come in many different sizes (Up to 20x20 maps or 2560x2560 pixels)."
  '4':
    - "<gradient:#0F4E73:#719FBA><b>Advertising</b></gradient>"
    - "<gradient:#3390C8:#58B9F3><b>Images</b></gradient>"
    - ""
    - "After you've chosen an ad-screen you need to set an image by clicking the frame item at the top. The image needs to have the same size as the ad-screen<hover:show_text:'<color:white><b>Comment 1</b></color>\n<color:gray>You can calculate the required width and\nheight using this formula:\n<color:#D0D0D0>ᴡɪᴅᴛʜ_ᴏʀ_ʜᴇɪɢʜᴛ_ᴏꜰ_ᴀᴅ_ꜱᴄʀᴇᴇɴ × 128</color></color>'><b><color:dark_gray>*</color></b></hover>."
    - "<color:#8A8A8A>Note: You can only submit images from whitelisted sites.</color>"
  '5':
    - "<gradient:#0F4E73:#719FBA><b>Advertising</b></gradient>"
    - "<gradient:#3390C8:#58B9F3><b>Image dithering</b></gradient>"
    - ""
    - "Map-Ads supports image dithering<hover:show_text:'<color:white><b>Comment 1</b></color>\n<color:gray>Dithering in image processing is a technique\nused to simulate colors or shading.</color>'><b><color:dark_gray>*</color></b></hover>.\nYou can choose between two dithering modes: <underlined><color:dark_gray>None</color></underlined> and <underlined><color:dark_gray>Floyd-Steinberg</color></underlined>.\nChange the dithering mode by clicking the amethyst shard at the top."
  '6':
    - "<gradient:#0F4E73:#719FBA><b>Advertising</b></gradient>"
    - "<gradient:#3390C8:#58B9F3><b>Time</b></gradient>"
    - ""
    - "You can increment and decrement the amount of minutes you want to purchase by clicking the gold & iron nugget at the top right corner. This will change the price (visible by hovering over the gold ingot at the bottom)."
  '7':
    - "<gradient:#0F4E73:#719FBA><b>Advertising</b></gradient>"
    - "<gradient:#3390C8:#58B9F3><b>Confirming</b></gradient>"
    - ""
    - "When you're done cusomizing the ad you can click the green concrete at the bottom right. This will check everything and create the ad<hover:show_text:'<color:white><b>Comment 1</b></color>\n<color:gray>Advertisements will have to be manually\nreviewed by staff. If the staff does not\naccept your ad you will receive your\nmoney back.</color>'><b><color:dark_gray>*</color></b></hover> if no errors are found. If there's an error a bell will appear at the bottom left."
  '8':
    - "<gradient:#0F4E73:#719FBA><b>Previewing</b></gradient>"
    - ""
    - "Map-Ads provides a command to preview your images (<hover:show_text:'<color:white><b>Command:</b></color>\n<color:light_purple>/mapads preview <none/floyd_steinberg> <image url></color>\n\n<color:white><b>Example:</b></color>\n<color:yellow>/mapads preview floyd_steinberg https://cerus.dev/example.png</color>\n\n<color:gray>Parameter 1 = Dither mode (none or floyd_steinberg)\nParameter 2 = Image url</color>'><underlined>hover</underlined></hover>).\nAfter running the command the plugin will let you choose an ad-screen to preview the image on. The image will only be visible to you."
  '9': [ ]
  '10':
    - "\n\n\n\n\n\n\n\n\n\n"
    - "        <b><rainbow>Map-Ads</rainbow></b>"
    - "<gray>Made with <dark_red>❤</dark_red> by <gradient:#17DB7E:#1792DB><b><click:open_url:https://github.com/cerus><hover:show_text:'<gray>Open <b><color:#8A8A8A>GitHub</color></b> page</gray>'>Cerus</hover></click></b></gradient></gray>"
```


# Language file

You can edit every message, item name and item lore (with the exception of a few cases) by editing the `lang.yml` file.

German translation: [Click here](https://pastebin.com/eMW7G9dF)

```yaml
'ver': "4"
'prefix': "&6&lM&e&lap-&6&lA&e&lds &8» &r"

'api,event,create,cancelled': "Advert creation has been cancelled by an external plugin"
'api,event,review,cancelled': "&cFailed to review advert: Cancelled by an external plugin"

'error,invalid_dimension_format': "&cInvalid dimension format"
'error,dimension_big': "&cDimensions are too big"
'error,invalid_url': "&cInvalid url"
'error,untrusted_site': "&cWebsite is not trusted"
'error,invalid_dither': "&cInvalid dither mode. Please choose one of the following: &7%s"
'error,failed_image': "&cFailed to get image. &7(%s)"
'error,image_big': "&cImage is too big. &7(%s > %s)"
'error,image_dimensions': "&cImage has invalid dimensions. &7The image needs to have a size of %dx%d pixels (image size: %dx%d)"
'error,cooldown': "&cPlease wait %dm %ds before doing this again."
'error,not_image': "&cUrl does not lead to an image"
'error,content_not_image': "&cUrl leads to content of type '%s' which is not an image type"
'error,content_unsupported_image': "&cUrl leads to content of type '%s' which is not a supported image type"
'error,no_screens': "&cThere are no ad-screens that can hold an image of this size."
'error,screen_not_found': "&cAd-screen not found"
'error,screen_broken': "&cAd-screen is broken &7(Map screen not found)"
'error,name_taken': "&cName is already taken"
'error,does_not_exist': "&cMap screen #%d does not exist"
'error,transition_not_found': "&cTransition not found"
'error,expected_screen_or_size': "&cInvalid argument! Expected screen id or size"
'error,advert_not_found': "&cAdvert not found"
'error,group_exists': "&cA group with this id already exists"
'error,group_not_found': "&cGroup does not exist"
'error,group_contains': "&cThis screen is already part of this group"
'error,group_not_contains': "&cThis screen is not part of this group"

'success,def_img_changed': "&aThe default image for %dx%d has been changed!"
'success,def_img_changed_new': "&aThe default image for %s has been changed!"
'success,def_img_removed': "&aThe default image for %s has been removed!"
'success,preview': "&aThe image will be displayed on ad-screen &e'%s' &afor one minute."
'success,created': "&aAd-screen '%s' has been created"
'success,updated': "&aAd-screen has been updated"
'success,deleted': "&aAd-screen has been deleted"
'success,ad_deleted': "&aAdvert has been deleted"
'success,group_created': "&aGroup '%s' (%s) was created"
'success,group_deleted': "&aGroup '%s' (%s) was deleted"
'success,group_screen_added': "&aScreen %s has been added to group '%s'"
'success,group_screen_removed': "&aScreen %s was removed from group '%s'"

'misc,please_wait': "&7&oPlease wait..."
'misc,visible': "&eThe image on the ad-screen is only visible to you."
'misc,img_viewing': "&7You are no longer viewing the image."
'misc,broken_screen,0': "&cAd-screen '%s' is broken! &7(Map-screen not found)"
'misc,broken_screen,1': "&7You can fix this by setting a new map screen: &e/mapads screen set screenid %s <Map screen id>"
'misc,pending': "&7There are &d%d adverts &7that are waiting to be reviewed. (&e/mapads review list&7)"
'misc,update,0': "&aA new Map-Ads update is available!"
'misc,update,1': "&e%s"
'misc,intensive_transition': "&c⚠ &eWarning: &7This transition is marked as performance intensive. &c⚠"

'gui,page': "&bPage %d"
'gui,prev_page,enabled': "&7« &fPrevious page"
'gui,prev_page,disabled': "&8« &7Previous page"
'gui,next_page,enabled': "&fNext page &7»"
'gui,next_page,disabled': "&7Next page &8»"
'gui,list,title': "Ad-screens"

'gui,confirm,yes': "&aYes"
'gui,confirm,no': "&cNo"

'gui,create,title': "Create advertisement"
'gui,create,format,day': "%dd "
'gui,create,format,hour': "%dh "
'gui,create,format,minute': "%dm"
'gui,create,button,map,name': "&eChoose an ad-screen"
'gui,create,button,map,lore,noscreen': [ "&7You did not choose an ad-screen yet." ]
'gui,create,button,map,lore,screen': [ "&f{0} &7({1}x{2})" ]
'gui,create,button,frame,name': "&aSet your image"
'gui,create,button,frame,lore': [ "&7No image set", " ", "&7Whitelisted sites:", "&f{0}" ]
'gui,create,button,glow_frame,name': "&aSet your image"
'gui,create,button,glow_frame,lore': [ "&f{0}" ]
'gui,create,button,book,name': "&2Help"
'gui,create,button,book,lore': [ "&7Click to open the Map-Ads help." ]
'gui,create,button,gold,name': "&6$%.2f"
'gui,create,button,amethyst,name': "&dImage dithering"
'gui,create,button,amethyst,lore': [ "&7Click to change the dithering algorithm.", "&7Dithering algorithm: &e{0}", " ",
                                     "&fWhat is image dithering?", "&7Dithering in image processing is a technique",
                                     "&7used to simulate colors or shading." ]
'gui,create,button,purchase,name,enabled': "&aPurchase ad"
'gui,create,button,purchase,name,disabled': "&7Purchase ad"
'gui,create,button,cancel,name,enabled': "&cCancel"
'gui,create,button,cancel,name,disabled': "&8Cancel"
'gui,create,button,minus_min,name': "&7&l-"
'gui,create,button,minus_min,lore': [ "&fDecrease the minutes you want to purchase by {0}", "&fClick+SHIFT to select minimum minutes" ]
'gui,create,button,plus_min,name': "&6&l+"
'gui,create,button,plus_min,lore': [ "&fIncrease the minutes you want to purchase by {0}", "&fClick+SHIFT to select maximum minutes" ]
'gui,create,button,info_min,name': "&8« &b%s &8»"
'gui,create,button,info_min,lore': [ "&7Minimum: &f{0}", "&7Maximum: &f{1}" ]
'gui,create,error,choose_screen_first': "Please choose a screen first"
'gui,create,error,choose_image_first': "Please choose an image first"
'gui,create,error,invalid_url': "Invalid url"
'gui,create,error,untrusted_site': "Website is not trusted"
'gui,create,error,not_image': "Url does not lead to an image"
'gui,create,error,content_not_image': "Url leads to content of type '%s' which is not an image type"
'gui,create,error,content_unsupported_image': "Url leads to content of type '%s' which is not a supported image type"
'gui,create,error,too_big': "Image is too big. Max size is %s but image is %s"
'gui,create,error,invalid_dimensions': "Image has invalid dimensions. Required dimensions are %dx%d but image is %dx%d"
'gui,create,error,no_money': "You don't have enough money"
'gui,create,error_image,0': "&c❌ Url is not whitelisted"
'gui,create,error_image,1': "&c❌ Image is too big"
'gui,create,error_image,2': "&c❌ Image width & height is not %dx%d"
'gui,create,error_image,3': "&c❌ Url does not lead to an image"
'gui,create,error_image,def': "Unknown error"
'gui,create,misc,enter_url': "Enter image url"
'gui,create,misc,confirming_image': "&7Checking image..."
'gui,create,misc,broadcast': "&bA new advert is waiting for a review! &e/mapads review list"

'gui,details,title': "Advertisement"
'gui,details,button,info,name': "&6Advertisement"
'gui,details,button,info,lore': [ "&8» &7By &e{0}", "&8» &7Purchased &e{1} &7for &6${2}", "&8» &7Ad-screen '&e{3}&7'", " ", "&b{4}" ]
'gui,details,button,viewimg,name': "&eView image"
'gui,details,button,accept,name': "&aAccept"
'gui,details,button,accept,confirm,title': "Confirmation"
'gui,details,button,accept,confirm,name': "&fAre you sure?"
'gui,details,button,accept,confirm,lore': [ "&7This action cannot be undone." ]
'gui,details,button,deny,name': "&cDeny"
'gui,details,button,deny,confirm,title': "Confirmation"
'gui,details,button,deny,confirm,name': "&fAre you sure?"
'gui,details,button,deny,confirm,lore': [ "&7This action cannot be undone." ]
'gui,details,button,back,name': "&7Go back"

'gui,reviewlist,title': "Pending advertisements"

'gui,adverts,title': "Advertisements"
'gui,adverts,item,name': "&3Advert from {name}"
'gui,adverts,item,lore,reviewed,yes': "&aYes"
'gui,adverts,item,lore,reviewed,no': "&cNo"
'gui,adverts,item,lore': [ "&8» &7Screen: &b{screen}", "&8» &7Price: &6{price}", "&8» &7Minutes remaining: &e{minrem} of {mintotal}",
                           "&8» &7Reviewed: {review}", "&8» &7Created: &f{created}" ]

'gui,advdetails,title': "Manage advertisement"
'gui,advdetails,button,delete,name': "&cDelete ad"
'gui,advdetails,button,delete,lore': [ "&7Clicking this button will delete", "&7the ad.", "&4Warning: &7This cannot be undone!" ]
'gui,advdetails,button,review,name': "&aReview ad"
'gui,advdetails,button,review,lore': [ "&7This advertisement has not been reviewed", "&7yet. Clicking this button will bring up",
                                       "&7the review GUI." ]

'command,advert,remove,confirm,name': "&fDo you want to delete this ad?"
'command,advert,remove,confirm,lore': [ "&4Warning: &7This cannot be undone." ]
```


# Discord integration

If you want to use the Map-Ads Discord integration you need to download the extension and drop the file into your plugins folder.

Staff members need the 'Manage messages' permission to accept/deny ads using the buttons.

[Download extension here](https://github.com/cerus-mc/map-ads/releases/download/1.2.25/map-ads-discord-bot-1.2.25.jar)

![How the default settings look like](https://i.imgur.com/OxnL0tL.png)

### Configuration

Default config (discord.yml):

```yaml
enable: false
token: "?"

storage:
  sqlite:
    path: "discord.db"

activity:
  online-status: "ONLINE" # ONLINE, IDLE, DO_NOT_DISTURB, INVISIBLE
  type: "WATCHING" # LISTENING, WATCHING, COMPETING
  text: "the server" # type + text = "watching the server"

time-format: "dd.MM.yyyy HH:mm:ss"
message:
  title: "Advertisement by {{PLAYER_NAME}}"
  description: |-
    Player {{PLAYER_NAME}} (`{{PLAYER_ID}}`) submitted a new advertisement
    ID: {{ADVERT_ID}}
    Date: {{TIME}} (<t:{{TIME_RAW}}:f>, <t:{{TIME_RAW}}:R>)
    Screen: {{SCREEN}}
    Purchased minutes: {{MINUTES}} for ${{PRICE}}
  color: "#00AFFE"
  image: "{{IMAGE_URL}}"
  #thumbnail: "{{IMAGE_URL}}"
  button:
    accept: "Accept ad"
    deny: "Deny ad"

channel-ids: [ ]
```

#### enable & token

`enable` is a simple toggle for enabling or disabling the extension. The `token` field holds your Discord bot token.

#### Creating a Discord bot token

1. Visit <https://discord.com/developers/applications> and log in with your Discord account
2. Click 'new application'
3. Enter a name of your choice and click 'create'
4. On the left sidebar click 'Bot'
5. Click 'add bot' and confirm
6. (Optional) Change the picture and username
7. (Optional) Disable 'public bot'
8. Click 'reveal token', copy the token and paste it into the 'token' field in the discord.yml file
9. On the left sidebar click 'OAuth2'
10. Scroll down and select the 'bot' scope
11. Scroll down even further and select the permissions (At least 'View channels', 'Send messages', 'Manage messages', 'Read message history')
12. Copy the link above the permissions selector and enter it into your browser
13. Select the server and invite the bot

#### activity

This controls the bot appearance.

`online-status`: Either `ONLINE`, `IDLE`, `DO_NOT_DISTURB` or `INVISIBLE`

`type`: Either `WATCHING`, `LISTENING` or `COMPETING`

`text`: Text of your choice, will be displayed next to the type ("Watching the server")

#### time-format

Format for dates and time (used for the {{TIME}} placeholder)

See [this page](https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html) for an explanation on how the format works

#### message

Controls the appearance of the message. The `image` and `thumbnail` fields are optional and can be removed. `color` has to be specified using hex.

Placeholders:

`{{PLAYER_NAME}}` - Player name

`{{PLAYER_ID}}` - Player uuid

`{{ADVERT_ID}}` - Advertisement ID

`{{TIME}}` - Formatted ad creation according to the specified format

`{{TIME_RAW}}` - Ad creation time in seconds (can be used for [Discord's time formatter](https://www.reddit.com/r/discordapp/comments/ob2h2l/comment/h3l4fxs/?utm_source=share\&utm_medium=web2x\&context=3))

`{{SCREEN}}` - Name of the ad screen

`{{MINUTES}}` - Purchased minutes

`{{PRICE}}` - Price paid

`{{IMAGE_URL}}` - Url of the submitted image

#### channel-ids

Enter the ID of every channel that should receive a message here. Example: `channel-ids: [ "123456789", "123567864" ]`

Check out [this article](https://support.discord.com/hc/en-us/articles/206346498-Where-can-I-find-my-User-Server-Message-ID-) if you don't know how to get your channel ids


# Economy plugins

Map-Ads supports the following economy plugins:

* [Vault](https://www.spigotmc.org/resources/34315/)
* [PlayerPoints](https://www.spigotmc.org/resources/80745/)
* AquaCore (<mark style="color:red;">untested</mark>)

If you would like to use Map-Ads with an unsupported economy plugin please open a ticket on my [Discord server](https://discord.gg/brb9eYp57E).


# Setup

## 1. Creating a map screen

{% tabs %}
{% tab title="Step 1" %}
Create an array of item frames in the desired width and height.

![](/files/-MlS6eXykjHBgWFU452R)
{% endtab %}

{% tab title="Step 2" %}
Look at the bottom left corner and type the command `/maps createscreen`.

![](/files/-MlS7-KbWlLZiiDsc01b)
{% endtab %}

{% tab title="Step 3" %}
Done!

![](/files/-MlS7BWb0mg6Rkzw7Tbv)
{% endtab %}
{% endtabs %}

## 2. Creating an ad-screen

Use the command `/mapads screen create NAME SCREENID` to create an ad-screen from a map screen. Replace NAME with a name of your choice (no spaces) and replace SCREENID with the id of the map screen you just created. Example: `/mapads screen create my_cool_screen 8`

## 3. Customizing the ad-screen

You can set a transition animation by using the command `/mapads screen set transition NAME TRANSITION`. Replace NAME with the name of your ad-screen and TRANSITION with the name of the transition. You can find all available transitions below. Example command usage: `/mapads screen set transition my_cool_screen shift`

{% tabs %}
{% tab title="instant" %}
![](/files/-MlS8SMVQ_x4Z-2zpYmQ)
{% endtab %}

{% tab title="gradual\_bar" %}
![](/files/-MlS8Z5ogCgFK_PBCR_j)
{% endtab %}

{% tab title="shift" %}
![](/files/-MlS8fhPAHJL0XsH9mXm)
{% endtab %}

{% tab title="pixelate\_big" %}
![](/files/-MlS8lv0XygjVo5_73dG)
{% endtab %}

{% tab title="pixelate\_small" %}
![](/files/-MlS8rLiNPiABlc_uGbo)
{% endtab %}

{% tab title="overlay" %}
![](https://i.imgur.com/Dd5Xwz0.gif)
{% endtab %}

{% tab title="alpha" %}
![Added in v1.2.0](https://i.imgur.com/wMSyEOr.gif)
{% endtab %}

{% tab title="growing" %}
![Added in v1.2.0](https://i.imgur.com/XAP9s27.gif)
{% endtab %}

{% tab title="shrinking" %}
![Added in v1.2.0](https://i.imgur.com/Z2CugjM.gif)
{% endtab %}

{% tab title="snake\_big" %}
![Added in v1.2.0](https://i.imgur.com/FmtFeRt.gif)
{% endtab %}

{% tab title="snake\_small" %}
![Added in v1.2.0](https://i.imgur.com/TDHy1aV.gif)
{% endtab %}

{% tab title="stripes" %}
![Added in v1.2.0](https://i.imgur.com/7D34rwD.gif)
{% endtab %}
{% endtabs %}

In addition to transitions you can also set a fixed price or fixed time for adverts. When a fixed time is set, all adverts on this screen will run for the time you specified. Players can not change the time. When a fixed price is specified, all adverts on this screen will cost the price you specified, regardless of the amount of minutes the player has selected.

To set a fixed time use `/mapads screen set fixedtime SCREEN TIME`. Replace SCREEN with an ad-screen id and TIME with the amount of time in minutes.

To set a fixed price use `/mapads screen set fixedprice SCREEN PRICE`. Replace SCREEN with an ad-screen id and PRICE with a price.

You can remove the fixed time and price with `/mapads screen remove fixedtime` and `/mapads screen remove fixedprice`.

## 4. Setting the default image

Don't forget to set a default image! The default image is shown if no ads are currently running and it will be shared across all ad-screens that have the same size. For example, if you change the default image for 3x2 ad-screens, all 3x2 ad-screens will use that default image. Since version 1.2.4 you can also set different default images for each screen.

You can set the default image with the `/mapads defaultimage set SIZE/SCREEN DITHER URL`command. Replace SIZE/SCREE with either a valid size (like 3x2, 10x10, 2x9) or a screen id, DITHER with either 'none' or 'floyd\_steinberg' and URL with a url pointing to a valid image of the same size. You can calculate the required image width and height using this formula: `width = ad_screen_width * 128, height = ad_screen_height * 128`

Examples:\
`/mapads defaultimage set 3x2 none https://example.com/image.png` will set a default image for all 3x2 screens.\
`/mapads defaultimage set screen1 none https://example.com/image.png` will set a default image for screen `screen1`. This will override any other default images.&#x20;

## 5. Creating screen groups

Since version 1.2.4 you can group your screens. Screen groups allow players to rent multiple screens at once for the same price.

You can create a screen group with the command `/mapads group create group_id Group Name`. Replace group\_id with a unique id (e.g. group1) and replace `Group Name` with a name of your choice (e.g. My Cool Group).

You can add screens to your group using the command `/mapads group screen add group_id screen_id`. Replace `group_id` with the id of a group you created and `screen_id` with the id of an ad screen.

You can remove screens from groups using `/mapads group screen remove group_id screen_id` and you can delete groups using `/mapads group remove group_id`.


# Developer API

## Installation

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

```xml
<repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
</repository>

<dependency>
    <groupId>com.github.cerus-mc</groupId>
    <artifactId>map-ads</artifactId>
    <version>Tag</version>
</dependency>
```

{% endtab %}

{% tab title="Gradle" %}

```groovy
allprojects {
    repositories {
        ...
	maven { url 'https://jitpack.io' }
    }
}

dependencies {
        implementation 'com.github.cerus-mc:map-ads:Tag'
}
```

{% endtab %}
{% endtabs %}

## Events

Map-Ads currently has two events: `AdvertCreateEvent` and `AdvertReviewEvent`. Both events can be cancelled.

The `AdvertCreateEvent` is called when a player tries to create an ad.

The `AdvertReviewEvent` is called when a staff member tries to review an ad.

## Transitions

Map-Ads allows you to create your own transitions. Just make a new class and implement the `Transition` interface:

```java
public class MyTransition implements Transition {

    @Override
    public void makeTransition(final @NotNull MapScreen screen, @Nullable final MapImage oldImg, final @NotNull MapImage newImg, final @NotNull TransitionRecorder recorder) {
        recorder.start(screen);
        
        // Make your transition here
        screen.getGraphics().fillComplete(ColorCache.rgbToMap(255, 255, 255));
        recorder.record(screen);
        screen.getGraphics().fillComplete(ColorCache.rgbToMap(0, 0, 0));
        recorder.record(screen);
        
        recorder.end(screen);
    
}
```

After that you can register the transition by calling `TransitionRegistry.register("my_transition", new MyTransition());`.

I encourage you to take a look at the [existing transitions](https://github.com/cerus-mc/map-ads/tree/main/plugin/src/main/java/dev/cerus/mapads/image/transition) to see how they work.

## Services

You can get an instance of the following services using the Bukkit service manager (`Bukkit.getServicesManager().getRegistration(ServiceClass.class).getProvider()` - You'll have to replace ServiceClass.class with the class of the service):

* AdvertStorage
* AdScreenStorage
* ImageStorage
* DefaultImageController
* ImageConverter
* ImageRetriever


# Transition recording format

The format for transition recordings is as follows:

```
{
  Header h,         // The header - See the 'Header' section
  Frame[h.frames] f // Array of frames - The amount can be found in the header
                    // Please note: The frame array is gzipped!
}
```

### Header

The header is always 15 bytes long.

```
Header {
  char[6] magic, // 6 bytes magic value, always MAPADS
  byte version,  // Currently 1
  int32 width,   // Width of the recorded transition
  int32 height,  // Height of the recorded transition
  int32 frames   // The amount of recorded frames
}
```

### Frame

Each frame can have a variable length.

```
Frame {
  int32 len,     // The amount of bytes in the following array
  byte[len] data // Array of colors
}
```


# FAQ

### Can I sync the ads on multiple servers?

Not really, the plugin was not designed for that. If you are in need of this feature you can request it on my Discord server.

### Where do I report bugs / request features / ask questions?

On my Discord server. Please note that I will only give support to purchasers of the plugin. You can still file bug reports / feature requests without purchasing the plugin.

### Discord server?

<https://discord.gg/brb9eYp57E>


