Compare commits

...

2 Commits

Author SHA1 Message Date
cc537f6a5b Дискорд-бот 2025-07-14 16:17:53 +03:00
53394d2e72 Image frame lobby 2025-07-14 15:42:49 +03:00
27 changed files with 1606 additions and 0 deletions

9
.dockerignore Normal file
View File

@ -0,0 +1,9 @@
src/plugins/ImageFrame/data
src/plugins/ImageFrame/players
src/plugins/ImageFrame/upload
src/map-color-cache.dat
src/plugins/DiscordSRV/accounts.aof

8
.gitignore vendored
View File

@ -9,6 +9,14 @@ world_the_end
./.console_history ./.console_history
src/plugins/ImageFrame/data
src/plugins/ImageFrame/players
src/plugins/ImageFrame/upload
src/map-color-cache.dat
src/plugins/DiscordSRV/accounts.aof
banned-ips.json banned-ips.json
banned-players.json banned-players.json
ops.json ops.json

BIN
plugins/DiscordSRV-Build-1.29.0.jar (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
420570541271810048 40427344-abb4-359c-9e1c-4a5d67f3a3a2

View File

@ -0,0 +1,122 @@
# Это - продвинутый функционал DiscordSRV, позволяющий отправлять сообщения в дискорд при каком-либо событии / вводе команды.
# Вам нужно знать, как работают события в Bukkit.
# Если вы не уверены в том, как это использовать - можете спросить знакомого разработчика, или присоединиться на наш дискорд-сервер @ discordsrv.com/discord
# Made something you'd like to share? You can do so in our Discord server's #alerts forum (invite above)
#
# Ссылка на документацию Bukkit API:
# https://hub.spigotmc.org/javadocs/bukkit
# Полезные штуки, которые помогут понять как работает SpEL:
# https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/expressions.html
# https://dzone.com/articles/learn-spring-expression-language-with-examples
#
# Вы можете использовать следующие заполнители:
# {tps} - Средний TPS серверп
# {time} - Текущее время
# {date} - Текущая дата
# {name} - (для PlayerEvent) имя игрока
# {ping} - (для PlayerEvent) пинг игрока
# {username} - (для PlayerEvent) имя игрока
# {displayname} - (для PlayerEvent) ник игрока
# {usernamenoescapes} - if alert is for a player event, the username of the player without escaping discord format (for use in inline code & code block markdown)
# {displaynamenoescapes} - if alert is for a player event, the display name of the player without escaping discord format (for use in inline code & code block markdown)
# {world} - (для PlayerEvent) мир, в котором находится игрок
# {embedavatarurl} - если PlayerEvent, то ссылка на аватар игрока, иначе на аватар бота
# {botavatarurl} - ссылка на аватар бота
# {botname} - имя бота
# %placeholder% - любые шаблоны PlaceholderAPI
#
# Вы также можете использовать выражения SpEL через ${expression...}, например...
# - Получить IP игрока: ${#player.address.address.hostAddress}
# - Получить игровой режим игрока: ${#player.gameMode.name()}
# - Получить id привязанного аккаунта в Discord у игрока: ${#discordsrv.accountLinkManager.getDiscordId(#player.uniqueId)}
# - Получить количество игроков на сервере: ${#server.onlinePlayers.size()}
# - Проверить статус DiscordSRV: ${#jda.status.name()}
# - Проверить, находится ли игрок в определённом мире: ${#player.world.name == 'world_the_end'}
# - Проверить, светит ли солнце в том мире, в котором сейчас игрок: ${#player.world.time > 0 && #player.world.time < 13000}
# Вы можете использовать следующие плейсхолдеры:
# #plugins.<plugin> - указанный плагин (null, если не существует)
# #event - Событие, которое отправит уведомление (если это уведомление действительно отправляется событием)
# #server - Эквивалент Bukkit#getServer
# #discordsrv - объект плагина DiscordSRV
# #player - игрок, который вызвал событие / отправил команду
# #sender - отправитель команды
# #command - полная команда (без слеша в начале)
# #args - аргументы команды
# #allArgs - аргументы команды как единая строка
# #channel - канал, в который будет отправлено это уведомление
# #jda - объект DiscordSRV JDA, нужен чтобы общаться с дискордом
#
# Синтаксис/стандартное:
# - Trigger: <название события либо /команда>
# Conditions:
# - property == < > <= >= value и т. д.
# Channel: <discordsrv channel name>
# IgnoreCancelled: true # Только для событий
# Content: ""
# Webhook:
# Enabled: false
# AvatarUrl: "{botavatarurl}"
# Name: "{botname}"
# Embed:
# Enabled: true
# Color: "#00ff00" # принимает шестнадцатеричный цветовой код (напр. "#ffffff") либо RGB-число (напр. 0)
# Author:
# ImageUrl: "{embedavatarurl}"
# Name: "{username} сделал... Что-то."
# Url: ""
# ThumbnailUrl: ""
# Title:
# Text: ""
# Url: ""
# Description: ""
# Fields: [] # Формат - "title;value;inline" (напр. "Кто вошёл?;%displayname%;true") либо "blank", чтобы добавить пустое поле
# ImageUrl: ""
# Footer:
# Text: ""
# IconUrl: ""
# Timestamp: false # поставьте на true, чтобы использовать время, в которое было отправлено сообщение, иначе будет использоваться unix-timestamp для конкретного времени (https://www.epochconverter.com/)
#
Alerts:
# Конфиг-образец, отправляет сообщение в канал "fish", когда игрок ловит рыбу
#- Trigger: PlayerFishEvent
# Channel: fish
# Conditions:
# - state.name() == 'CAUGHT_FISH'
# Embed:
# Color: "#00ff00"
# Author:
# ImageUrl: "{embedavatarurl}"
# Name: "{name} поймал ${caught.itemStack.type.name()}!"
# Конфиг-образец, чтобы отправлять уведомления античита Matrix
#- Trigger: PlayerViolationEvent
# Channel: matrix
# Conditions:
# - violations >= 5 # Не отправлять инфу про тех, у кого меньше 5 нарушений
# Embed:
# Color: "#ff0000"
# Author:
# ImageUrl: "{embedavatarurl}"
# Name: "{username} попался на проверке ${hackType.name().toLowerCase()} | ${component} | vl:${violations} ping:${player.handle.ping} tps:{tps}"
# Конфиг-образец, отправляет сообщение всякий раз, когда кто-то использует /gamemode
#- Trigger: /gamemode
# Channel: gamemode
# Conditions:
# - '#player.hasPermission("minecraft.command.gamemode") == true'
# Embed:
# Color: "#ff0000"
# Author:
# ImageUrl: "{embedavatarurl}"
# Name: "{username} изменил игровой режим на ${#args.get(0)}"
# Конфиг-образец, отправляет сообщение всякий раз, когда кто-то использует /me
#- Trigger: /me
# Channel: me
# Conditions:
# - '#player.hasPermission("minecraft.command.me") == true || #player.hasPermission("essentials.me") == true'
# Embed:
# Color: "#00ff00"
# Author:
# ImageUrl: "{embedavatarurl}"
# Name: "* {username} ${#allArgs}"

View File

@ -0,0 +1,354 @@
# DiscordSRV Configuration
# Нужна помощь? Присоединяйтесь к нашему Discord, https://discordsrv.com/discord
# Не трогайте это пожалуйста!
ConfigVersion: 1.29.0
# Токен бота; не знаете что это? Просмотрите видео по установке и настройке плагина
# После изменения этого параметра необходимо перезагрузить сервер.
BotToken: "MTM5NDIzMDUwNDU1OTA4MzY0Mg.G8KT1s.-zRMQZBkmVoHX7w0qdicoNk2NSqUl6euCTv55I"
# Ссылки на каналы из игры в Discord
# синтаксис: Channels: {"название внутриигрового канала из Minecraft": "числовой идентификатор канала из Discord", "другое название внутриигрового канала из Minecraft": "другой числовой идентификатор канала из Discord"}
#
# Все сообщения DiscordSRV будут идти на первый канал, если не определен канал для этого типа сообщений:
# при использовании совместимого плагина чата имя канала будет тем же, что и в этом плагине (для сообщений чата)
# - Если вы используете TownyChat, канал по умолчанию обычно называется "general", а не "global".
# для сообщений в чате игрока (если не используется плагин чата): global
# для сообщений о запуске / остановке сервера: status
# для сообщений о достижении / продвижении: awards
# для сообщений о смерти: deaths
# для сообщений о присоединении: join
# для сообщений о выходе: leave
# для сообщений dynmap: dynmap
# для сообщений сторожевого таймера: watchdog
# для /discord broadcast: broadcasts (если не указано в команде)
# Ссылка на аккаунт: link
#
# Первая часть пар каналов не является названием канала Discord!
# Выполните "/discord reload" после изменения этого опции для применения
Channels: {"global": "1394245250096173076"}
# Канал для вывода сообщений Консоли (НЕ ИМЯ); оставьте пустым, чтобы отключить консольный канал
DiscordConsoleChannelId: ""
# Ссылка на приглашение, отображаемая игрокам при использовании /discord, и в сообщении, отображаемом несвязанным игрокам при обязательной привязке.
DiscordInviteLink: "https://discord.gg/xsyy7d8RfG"
# Эксперименты
# Эти функции не полностью оптимизированы; Используйте на свой риск
# JDBC (MySQL/MariaDB)
Experiment_JdbcAccountLinkBackend: "jdbc:mysql://HOST:PORT/NAME?autoReconnect=true&useSSL=false"
Experiment_JdbcTablePrefix: ""
Experiment_JdbcUsername: ""
Experiment_JdbcPassword: ""
# Webhook Delivery
Experiment_WebhookChatMessageDelivery: false
Experiment_WebhookChatMessageUsernameFormat: "%displayname%"
Experiment_WebhookChatMessageFormat: "%message%"
Experiment_WebhookChatMessageUsernameFromDiscord: false
Experiment_WebhookChatMessageAvatarFromDiscord: false
Experiment_WebhookChatMessageUsernameFilters: {}
# Встраивание и формат URL-адреса изображения / аватара веб-перехватчика
# Оставьте пустым, чтобы использовать значение по умолчанию
# Доступные заполнители: {texture} {username} {uuid} {uuid-nodashes} {size}
AvatarUrl: "https://mc-heads.net/avatar/%skinsrestorer_texture_id_or_steve%.png#{username}"
# Reserializer
# Преобразует форматирование (жирный, курсив, подчеркивание) между Minecraft и Discord
Experiment_MCDiscordReserializer_ToDiscord: true
Experiment_MCDiscordReserializer_ToMinecraft: true
Experiment_MCDiscordReserializer_InBroadcast: false
# Другие
CancelConsoleCommandIfLoggingFailed: true
ForcedLanguage: none
ForceTLSv12: true
NoopHostnameVerifier: false
MaximumAttemptsForSystemDNSBeforeUsingFallbackDNS: 3
TimestampFormat: EEE, d. MMM yyyy HH:mm:ss z
DateFormat: yyyy-MM-dd
# https://docs.discordsrv.com/config/#Timezone
Timezone: default
# MinecraftMentionSound: Должен ли звук посылаться игроку в Minecraft при упоминании из Discord
MinecraftMentionSound: true
# Подключаемые модули
# После изменения этих параметров необходимо перезагрузить сервер.
#
# DisabledPluginHooks: отключить модули (обычно это названия плагинов).
# VentureChatBungee: включает BungeeCord-функционал модуля VentureChat (сообщения принимаются с каждого сервера, требуется, чтобы по крайней мере 1 игрок был в сети)
# EnablePresenceInformation: enabled presence information, which is required for some of our PlaceholderAPI placeholders. Keep in mind this requires the "Presence Intent" from the Discord developer portal
# UseModernPaperChatEvent: only use this if you have a chat plugins that SPECIFICALLY utilizes Paper's "AsyncChatEvent"
DisabledPluginHooks: []
VentureChatBungee: false
EnablePresenceInformation: false
UseModernPaperChatEvent: false
# Информация в статусе бота в Discord
# Устанавливает боту статус
# Может быть как одним статическим значением, так и несколькими (сменяющимися друг за другом).
# Вы можете добавить в начало "playing", "watching", "listening to" или "competing", чтобы установить тип активности (играет, смотрит, слушает, соревнуется)
# Также вы можете поставить свой кастомный статус без префикса
# %online%: number of online players
# Поддерживает шаблоны PlaceholderAPI
#
# DiscordGameStatus: Отображаемый текст. Может быть как одним значением, например "Minecraft", так и несколькими: ["Minecraft", "yourip.changeme.com"]
# DiscordOnlineStatus: Статус отображаемого действия. Он должен быть одним из следующих: ONLINE, DND, IDLE или INVISIBLE.
# StatusUpdateRateInMinutes: Как часто (в минутах) менять статус (если их несколько)
DiscordGameStatus: ["Синхронизирует Бебру"]
DiscordOnlineStatus: ONLINE
StatusUpdateRateInMinutes: 2
# Настройка канала чата
# Канал чата предназначен для вывода всех внутриигровых сообщений, а также всех публичных сообщений, которыми обмениваются игроки
# вашего сервера
#
# DiscordChatChannelDiscordToMinecraft: отправлять или не отправлять сообщения из канала чата в чат Minecraft (Discord -> Minecraft)
# DiscordChatChannelMinecraftToDiscord: отправлять или не отправлять сообщения из чата Minecraft в канал чата (Minecraft -> Discord)
# DiscordChatChannelTruncateLength: максимальная длина сообщений из Discord для отправки в чат Minecraft
# DiscordChatChannelTranslateMentions: переводить или не переводить упоминания такие как @Person для сообщений Minecraft в Discord
# DiscordChatChannelAllowedMentions: типы упоминаний, разрешенные в сообщениях Minecraft to Discord; типы, отсутствующие в значении по умолчанию: "роль", "здесь" и "все"
# DiscordChatChannelEmojiBehavior: как смайлики должны быть отправлены в Минекрафт. Может быть "show", "name" или "hide".
# DiscordChatChannelEmoteBehavior: как эмоты должны быть отправлены в Минекрафт. Может быть "name" или "hide".
# DiscordChatChannelPrefixRequiredToProcessMessage: символ(ы), необходимые как префикс сообщений для их отправки из Minecraft в Discord (например, «!»)
# DiscordChatChannelPrefixActsAsBlacklist: Должен ли префикс действовать как черный список.
# DiscordChatChannelRolesAllowedToUseColorCodesInChat: список ролей, которым разрешено использовать цвета/форматирование в чате Discord в Minecraft
# DiscordChatChannelBroadcastDiscordMessagesToConsole: выводить или нет обработанные Discord сообщения в игровую консоль
# DiscordChatChannelRequireLinkedAccount: требовать ли привязку аккаунта при отправке сообщения из Discord в Minecraft
# DiscordChatChannelBlockBots: блокировать ли ботам возможность отправлять сообщения из Discord в Minecraft
# DiscordChatChannelBlockWebhooks: следует ли блокировать ботов в чате Discord -> MC
# DiscordChatChannelBlockedIds: идентификаторы пользователей (или ботов), заблокированных для отсылки сообщений из Discord в Minecraft
# DiscordChatChannelBlockedRolesAsWhitelist: если следующий список следует рассматривать как белый список (true) или черный список (false)
# DiscordChatChannelBlockedRolesIds: идентификаторы ролей Discord, сообщения которых не должны обрабатываться и отправляться в MC
# DiscordChatChannelRolesSelectionAsWhitelist: если следующий список следует рассматривать как белый список (true) или черный список (false)
# DiscordChatChannelRolesSelection: список ролей, которые должны быть отфильтрованы по всем ролям пользователя.
# DiscordChatChannelRoleAliases: список псевдонимов ролей (альтернативные имена для ролей для использования в сообщениях Minecraft)
#
DiscordChatChannelDiscordToMinecraft: true
DiscordChatChannelMinecraftToDiscord: true
DiscordChatChannelTruncateLength: 256
DiscordChatChannelTranslateMentions: true
DiscordChatChannelAllowedMentions: [user, channel, emote]
DiscordChatChannelEmojiBehavior: "name"
DiscordChatChannelEmoteBehavior: "name"
DiscordChatChannelPrefixRequiredToProcessMessage: "!д"
DiscordChatChannelPrefixActsAsBlacklist: false
DiscordChatChannelRolesAllowedToUseColorCodesInChat: ["Developer", "Owner", "Admin", "Moderator"]
DiscordChatChannelBroadcastDiscordMessagesToConsole: true
DiscordChatChannelRequireLinkedAccount: false
DiscordChatChannelBlockBots: false
DiscordChatChannelBlockWebhooks: true
DiscordChatChannelBlockedIds: ["000000000000000000", "000000000000000000", "000000000000000000"]
DiscordChatChannelBlockedRolesAsWhitelist: false
DiscordChatChannelBlockedRolesIds: ["000000000000000000", "000000000000000000", "000000000000000000"]
DiscordChatChannelRolesSelectionAsWhitelist: false
DiscordChatChannelRolesSelection: ["Don't show me!", "Misc role"]
DiscordChatChannelRoleAliases: {"Developer": "Dev"}
# Настройка чата консоли
# Канал или чат консоли - это текстовый канал, который интерпретирует все отслылаемые из Discord сообщения как команды консоли,
# а также транслирует все события, сообщения и команды консоли сервера в Discord
#
# Вы можете настроить формат всех сообщений (включая удаление временных меток) в конфигурационном файле messages.yml
#
# DiscordConsoleChannelLogRefreshRateInSeconds: скорость в секундах между отправкой сообщений из консоли
# DiscordConsoleChannelUsageLog:
# %date%: текущая дата
# пример: 2017-01-01
# PlaceholderAPI заполнители поддерживаются
# DiscordConsoleChannelBlacklistActsAsWhitelist: инвертировать ли "чёрный" список команд, превращая его в "белый"
# DiscordConsoleChannelBlacklistedCommands: фразы, заключенные в кавычки, которые пользователи не могут отправлять в виде команд в консоль
# DiscordConsoleChannelFilters: фильтры регулярных выражений, которые будут применяться к консольным строкам, отправляемым в Discord, если результат пуст, сообщение не будет отправлено вообще
# DiscordConsoleChannelLevels: типы логов, которые отправляются в консольный канал
# DiscordConsoleChannelUseCodeBlocks: если консоль должна быть завернута в блоки кода и окрашена
# DiscordConsoleChannelBlockBots: разрешить ли ботам отправлять команды в канале консоли
#
DiscordConsoleChannelLogRefreshRateInSeconds: 5
DiscordConsoleChannelUsageLog: "Console-%date%.log"
DiscordConsoleChannelBlacklistActsAsWhitelist: false
DiscordConsoleChannelBlacklistedCommands: ["?", "op", "deop", "execute"]
DiscordConsoleChannelFilters: {".*(?i)async chat thread.*": "", ".*There are \\d+ (?:of a max of|out of maximum) \\d+ players online.*": ""}
DiscordConsoleChannelLevels: [info, warn, error]
DiscordConsoleChannelUseCodeBlocks: true
DiscordConsoleChannelBlockBots: true
# Настройка выполнения команд в канале чата
# Эти опции позволяют настроить выполнение определённых команды на серверной консоли
# скажем, вот так "!c kick Notch"
#
# DiscordChatChannelConsoleCommandEnabled: разрешать или запрещать консольные команды из канала чата.
# DiscordChatChannelConsoleCommandNotifyErrors: отправлять или не отправлять сообщение об ошибке при попытке использовать команду, не имея прав
# DiscordChatChannelConsoleCommandPrefix: префикс для использования в консольных командах. например "!c tps"
# DiscordChatChannelConsoleCommandRolesAllowed: роли, которым разрешено выполнять команды сервера из канала чата
# DiscordChatChannelConsoleCommandWhitelist: список команд, которые могут быть запущены с помощью DiscordChatChannelConsoleCommandPrefix
# DiscordChatChannelConsoleCommandWhitelistBypassRoles: список ролей, которые обходят белый список
# DiscordChatChannelConsoleCommandWhitelistActsAsBlacklist: должен ли командный белый список действовать как черный список
# DiscordChatChannelConsoleCommandExpiration: время в секундах до тех пор, пока результат команды будет удален ботом. Установите значение 0, чтобы отключить истечение срока действия.
# DiscordChatChannelConsoleCommandExpirationDeleteRequest: удалить или не удалять сообщение игрока, который выполнил команду
#
DiscordChatChannelConsoleCommandEnabled: false
DiscordChatChannelConsoleCommandNotifyErrors: false
DiscordChatChannelConsoleCommandPrefix: "!c"
DiscordChatChannelConsoleCommandRolesAllowed: ["Protektor", "Developer"]
DiscordChatChannelConsoleCommandWhitelist: ["say", "lag", "tps"]
DiscordChatChannelConsoleCommandWhitelistBypassRoles: ["Owner", "Developer"]
DiscordChatChannelConsoleCommandWhitelistActsAsBlacklist: false
DiscordChatChannelConsoleCommandExpiration: 0
DiscordChatChannelConsoleCommandExpirationDeleteRequest: true
# Особая команда вывода списка игроков в канале чата
# Да-да, все эти опции только для одной безобидной команды "playerlist"
#
# DiscordChatChannelListCommandEnabled: включена ли команда
# DiscordChatChannelListCommandMessage: команда, которую могут использовать игроки, чтобы вывести список игроков на сервере
# DiscordChatChannelListCommandExpiration: время в секундах, пока выведенный список пользователей не будет удалён ботом. установите значение 0, чтобы отключить истечение срока действия.
# DiscordChatChannelListCommandExpirationDeleteRequest: удалять ли сообщение игрока, который изначально запросил вывод списока игроков
#
DiscordChatChannelListCommandEnabled: true
DiscordChatChannelListCommandMessage: "playerlist"
DiscordChatChannelListCommandExpiration: 10
DiscordChatChannelListCommandExpirationDeleteRequest: true
# Чёрный список фраз и регулярных выражений для канала чата
#
# DiscordChatChannelGameFilters: фильтры регулярных выражений, которые будут применяться к сообщениям чата, отправляемым в Discord, если результат пуст, сообщение не будет отправлено вообще
# DiscordChatChannelDiscordFilters: фильтры регулярных выражений, которые будут применяться к сообщениям чата, отправляемым в Minecraft, если результат пуст, сообщение не будет отправлено вообще
#
DiscordChatChannelGameFilters: {}
DiscordChatChannelDiscordFilters: {".*Online players \\(.*": "", ".*\\*\\*No online players\\*\\*.*": ""}
# Настройки обновления темы канала
#
# ChannelTopicUpdaterChannelTopicsAtShutdownEnabled: должны ли темы канала быть вообще изменены при завершении работы сервера
# ChannelTopicUpdaterRateInMinutes: число минут между автоматическим обновлением тем канала со свежей информацией
#
ChannelTopicUpdaterChannelTopicsAtShutdownEnabled: false
ChannelTopicUpdaterRateInMinutes: 10
# Обновление канала
# Эта функция изменяет название указанных каналов, чтобы они соответствовали внутриигровым заполнителям.
# Опции:
# ChannelId: идентификатор канала для изменения (обязательно)
# Format: формат канала (обязательно). Доступные заполнители:
# %playercount%: текущее количество игроков
# %playermax%: максимальное количество игроков
# %date%: текущая дата и время
# %totalplayers%: общее количество игроков, когда-либо присоединившихся к основному миру
# %uptimemins%: количество минут с момента запуска DiscordSRV
# %uptimehours%: количество часов с момента запуска DiscordSRV
# %motd%: motd сервера
# %serverversion%: версия сервера, например Spigot-1.9.
# %freememory%: свободная память JVM в МБ
# %usedmemory%: используемая память JVM в МБ
# %totalmemory%: общий объем памяти JVM в МБ
# %maxmemory%: максимальная память JVM в МБ
# %freememorygb%: свободная память JVM в ГБ
# %usedmemorygb%: используемая память JVM в ГБ
# %totalmemorygb%: общий объем памяти JVM в ГБ
# %maxmemorygb%: максимальная память JVM в ГБ
# %tps%: среднее значение TPS сервера
# Заполнители PlaceholderAPI также поддерживаются
# ShutdownFormat: Формат, который должен принимать канал после выключения сервера. Доступные заполнители:
# %time% или %date%: текущая дата и время
# %serverversion%: версия сервера
# %totalplayers%: общее количество игроков, когда-либо присоединившихся к основному миру
# %timestamp%: текущая временная метка unix
# UpdateInterval: Время в минутах ожидания между обновлением имени канала (минимум 10 из-за ограничений скорости)
ChannelUpdater:
- ChannelId: "000"
Format: "%playercount% игроков онлайн"
ShutdownFormat: "Сервер отключен"
UpdateInterval: 10
- ChannelId: "000"
Format: "Текущий показатель TPS: %tps%"
ShutdownFormat: "Сервер отключен"
UpdateInterval: 10
# Заготовленные ответы
# Эти триггеры (команды в некотором роде), которые будут отправлять «заготовленный ответ» в ответ на них
# Возможно, вы захотите изменить их или добавить свои собственные
#
# Синтаксис {"TRIGGER": "RESPONSE", "TRIGGER": "RESPONSE", ...}
# Если вы не хотите использовать эту опцию, просто оставьте {}
# Кстати, доступны шаблоны PlaceholderAPI
#
DiscordCannedResponses: {"!ip": "bebrashield.net", "!site": "https://bebrashield.net"}
# Подключение аккаунта Minecraft к Discord
# Эти опции относятся к настройке связывания игрового аккаунта Minecraft с учётной записью Discord
#
# MinecraftDiscordAccountLinkedConsoleCommands: команды, подлежащие выполнению при связывании аккаунтов (см. ниже все возможные шаблоны)
# MinecraftDiscordAccountUnlinkedConsoleCommands: команды, подлежащие выполнению при разрыве связанных аккаунтов (см. ниже все возможные шаблоны)
# %minecraftplayername%: ник игрока Minecraft
# пример: Notch
# %minecraftuuid%: uuid игрока
# пример: вы знаете как выглядит uuid
# %discordid%: связанный ID аккаунта Discord
# пример: 12345678901234567890
# %discordname%: привязанный ник аакаунта Discord
# пример: Notch
#
# MinecraftDiscordAccountLinkedRoleNameToAddUserTo: имя или ID Discord роли, в которую будут добавлены пользователи, после того как привяжут свои аккаунты
# MinecraftDiscordAccountLinkedAllowRelinkBySendingANewCode: можно ли отправить новый код боту, чтобы перепривязать аккаунт
# MinecraftDiscordAccountLinkedUsePM: Связывание счетов с помощью PMs
# MinecraftDiscordAccountLinkedMessageDeleteSeconds: Время (в секундах) до удаления сообщения при связывании в текстовом канале. Установите значение 0, если вы не хотите удалять сообщение.
#
MinecraftDiscordAccountLinkedConsoleCommands: ["", "", ""]
MinecraftDiscordAccountUnlinkedConsoleCommands: ["", "", ""]
MinecraftDiscordAccountLinkedRoleNameToAddUserTo: "Бебра"
MinecraftDiscordAccountLinkedAllowRelinkBySendingANewCode: true
MinecraftDiscordAccountLinkedUsePM: true
MinecraftDiscordAccountLinkedMessageDeleteSeconds: 0
# Мониторинг сервера
#
# Мониторинг отслеживает состояние вашего сервера с момента последнего игрового такта (тика)
# Если время, прошедшее с момента последнего тика, превышает установленный таймаут в секундах, в чат Discord будет отправлено соответствующее сообщение
#
# ServerWatchdogEnabled: включён или нет мониторинг сервера в принципе
# ServerWatchdogTimeout: время в секундах, которое должно пройти с момента последнего тика, прежде чем будет отправлено сообщение (к примеру, Spigot использует 60 секунд)
# минимум для этого значения - 10 секунд
# ServerWatchdogMessageCount: количество раз отправки ServerWatchdogMessage. Полезно, если вы *действительно* хотите убедиться что что-то пошло не так
#
ServerWatchdogEnabled: true
ServerWatchdogTimeout: 30
ServerWatchdogMessageCount: 3
# HTTP proxy used for connecting to the Discord API
# Leave this alone if you don't understand what it does
ProxyHost: "example.com"
ProxyPort: 1234
ProxyUser: "USERNAME"
ProxyPassword: "PASSWORD"
# Отладочная информация
# Не включайте их, если вы не пытаетесь найти проблему
#
# Доступные категории отладки:
# MINECRAFT_TO_DISCORD - Сообщения из Minecraft
# DISCORD_TO_MINECRAFT - Сообщения из Discord
# GROUP_SYNC - Групповая синхронизация
# PRESENCE - Статус игры или присутствие бота
# VOICE - Голосовой модуль (см. voice.yml)
# REQUIRE_LINK - Требуемая ссылка для присоединения модуля (см. linking.yml)
# NICKNAME_SYNC - Псевдоним синхронизации
# ALERTS - Оповещения (см. alerts.yml)
# WATCHDOG - Мониторинг сервера
# BAN_SYNCHRONIZATION - Синхронизация банов
# LP_CONTEXTS - Контексты LuckPerm
# ACCOUNT_LINKING - привязка учетной записи Discord/Minecraft
#
# UNCATEGORIZED - Все, что не относится ни к одной из вышеуказанных категорий
# ALL - Все вышеперечисленные категории (включая UNCATEGORIZED)
#
# JDA - Отладочные сообщения JDA
# JDA_REST_ACTIONS - Для отладки остальных действий JDA
# CALLSTACKS - Отображает трассировку стека для вызовов отладки DiscordSRV
#
# Ex. "Debug: [GROUP_SYNC, PRESENCE]"
#
Debug: []

View File

@ -0,0 +1,57 @@
Require linked account to play:
Enabled: true
# Если вы не знаете, что это такое - не трогайте.
#
# Приоритет слушателя соединения
# В порядке от первого до последнего доступны следующие значения: LOWEST, LOW, NORMAL, HIGH, HIGHEST
# Возможно, вам придется изменить это на более поздний приоритет, чтобы плагин банов отключил игрока, прежде чем DiscordSRV откажет им
Listener priority: LOWEST
# Событие, когда модуль связи должен прослушивать и запрещать вход в систему
# Некоторые плагины белого списка используют AsyncPlayerPreLoginEvent (хорошо), некоторые используют PlayerLoginEvent (не так хорошо)
Listener event: AsyncPlayerPreLoginEvent
# Если вы не знаете, что это такое - не трогайте.
# Ники в Minecraft, которые могут заходить на сервер без подписки/привязки?
Bypass names: [Scarsz, Vankka]
# Имеют ли люди из ванильного вайтлиста право входить на сервер без подписки/привязки?
Whitelisted players bypass check: true
# Разрешить или запретить игрокам из бан-листа VANILLA связывать свои аккаунты
Check banned players: false
# Независимо от того, будут ли игроки, не включенные в банлист VANILLA, обходить необходимость связывать свои учетные записи / иметь дополнительную роль
Only check banned players: false
# Сообщение при кике игроков с просьбой связать их учетные записи
# Используйте {BOT} в качестве заполнителя для имени бота
# Используйте {CODE} в качестве заполнителя для кода, который надо отправить боту
# Используйте {INVITE} в качестве заполнителя для ссылки-приглашения, которая необходима людям для присоединения к серверу Discord (использует DiscordInviteLink, настроенный в config.yml)
Not linked message: "&7Вы должны связать свою учетную запись &9Discord&7, чтобы играть.\n\n&7Отправьте сообщение боту &b{BOT}&7 на сервере Discord с кодом &b{CODE}&7, чтобы привязать аккаунт.\n\n&7Ссылка-приглашение » &b{INVITE}"
# Если включено, игрокам нужно будет не только связать свои аккаунты, но и потребуется
# быть участником сервера Discord, на котором находится бот.
#
# Допустимые форматы:
# true/false: связанная учетная запись должна быть хотя бы на одном сервере Discord, на котором находится бот
# например: true
# <идентификатор сервера>: связанная учетная запись должна находиться на данном сервере Discord
# например: 135634590575493120
# [<идентификатор сервера>, <идентификатор сервера>, ...]: связанная учетная запись должна быть на ВСЕХ указанных серверах Discord
# например: [135634590575493120, 690411863766466590]
#
# Значение этой опции заменяется, если ниже указаны обязательные для вас роли подписчика.
Must be in Discord server: true
# Можно требовать не только привязку аккаунта, но и наличие специальной роли, например Twitch
Subscriber role:
Require subscriber role to join: false
Subscriber roles: ["00000000000000000", "00000000000000000", "00000000000000000"]
Require all of the listed roles: false # при значении false требуется только одна из указанных выше ролей, при true - все роли.
Kick message: "&cВы должны быть подписаны на Twitch, чтобы иметь возможность играть."
Messages:
DiscordSRV still starting: "&cВ настоящее время невозможно проверить состояние ссылки, поскольку сервер все еще подключается к Discord.\n\nПопробуйте еще раз через минуту."
Not in server: "&cВ настоящее время вы не являетесь частью нашего сервера Discord.\n\nПрисоединяйтесь на {INVITE}!"
Failed to find subscriber role: "&cНе удалось найти какую-либо роль подписчика на Discord.\n\nСвяжитесь с администраторами вашего сервера по этому вопросу."
Failed for unknown reason: "&cПроизошла ошибка при попытке подтвердить ваш аккаунт.\n\nОбратитесь к администратору сервера по этому вопросу."
Kicked for unlinking: "&cВы были кикнуты с сервера из-за отвязки аккаунта Discord.\n\nПожалуйста, перезайдите, чтобы снова связать аккаунты."

View File

@ -0,0 +1,449 @@
# Discord -> Minecraft сообщения
#
# DiscordToMinecraftChatMessageFormat: формат, используемый при отправке сообщений из Discord в Minecraft
# DiscordToMinecraftChatMessageFormatNoRole: формат, используемый при отправке сообщений из Discord в Minecraft, когда игроку не назначена роль
#
# Вы можете указать другой формат для каждого канала. Допустим, у вас есть канал с именем «mychannel».
# Если вы хотите, чтобы форматирование отличалось от глобального, вы можете добавить следующие свойства:
#
# DiscordToMinecraftChatMessageFormat_mychannel: "[&bDiscord From MyChannel &r| %toprolecolor%%toprole%&r] %name% » %message%"
# DiscordToMinecraftChatMessageFormatNoRole_mychannel: "[&bDiscord From MyChannel&r] %name% » %message%"
#
# Доступные шаблоны:
# %allroles%: все роли пользователя скомбинированные с помощью DiscordToMinecraftAllRolesSeparator между ними
# пример: Owner | Developer | Boss man
# %message%: содержимое сообщения
# пример: Hello!
# %toprole%: самая высокая роль пользователя
# пример: Owner
# %toprolealias%: псевдоним роли из DiscordChatChannelRoleAliases, в противном случае имя роли
# пример: Dev
# %toproleinitial%: первая буква высшей роли
# example: O
# %toprolecolor%: приблизительный цвет самой высокой роли пользователя
# пример: &4
# %name%: действующее имя человека на Discord (псевдоним, если присутствует, имя пользователя в противном случае)
# пример: NotchIsMe
# %username%: пользователя в Discord
# пример: Notch
# %userid%: person's ID on Discord
# example: 1081004946872352958
# %channelname%: имя канала, из которого поступает сообщение
# пример: server-chat
# %reply%: сообщение, отображаемое, когда сообщение является ответом на другое сообщение.
# Формат сообщения можно настроить с помощью DiscordToMinecraftMessageReplyFormat,
# это будет пусто, если сообщение не является ответом на другое сообщение
#
# DiscordToMinecraftAllRolesSeparator: разделитель между ролями в шаблоне %allroles%
#
# DiscordToMinecraftMessageReplyFormat: формат отображаемого сообщения, указывающего, что сообщение является ответом.
#
# Доступные заполнители:
# %name%: эффективное имя пользователя, которому отвечает в Discord (псевдоним, если присутствует, в противном случае имя пользователя)
# example: NotchIsMe
# %username%: имя пользователя, которому отвечают в Discord.
# пример: Notch
# %userid%: the ID of the user that is being replied to on Discord
# example: 1081004946872352958
# %message%: содержание сообщения, на которое идет ответ
#
# ПРИМЕЧАНИЕ: Заполнитель %reply% должен присутствовать в формате, если вы хотите, чтобы DiscordToMinecraftMessageReplyFormat отображался в вашем сообщении.
#
DiscordToMinecraftChatMessageFormat: "[<aqua>Discord</aqua> | %toprolecolor%%toprolealias%<reset>] %name%%reply% » %message%"
DiscordToMinecraftChatMessageFormatNoRole: "[<aqua>Discord</aqua>] %name%%reply% » %message%"
DiscordToMinecraftAllRolesSeparator: " | "
DiscordToMinecraftMessageReplyFormat: " (отвечая на %name%)"
# Minecraft -> Discord сообщения
#
# MinecraftChatToDiscordMessageFormat: формат, используемый при отправке сообщений из Minecraft в Discord
# MinecraftChatToDiscordMessageFormatNoPrimaryGroup: используется вместо MinecraftChatToDiscordMessageFormat
# когда основная группа игрока не задана или не найдена
#
# Доступные шаблоны:
# %username%: исходное имя игрока
# пример: jeb_
# %displayname%: отображаемое имя игрока, по типу ника
# пример: BigBossManJeb
# %usernamenoescapes%: исходное имя игрока без экранирования формата Discord (для использования во встроенном коде и уценке блока кода)
# example: jeb_
# %displaynamenoescapes%: отображаемое имя игрока, по типу ника без экранирования формата Discord (для использования во встроенном коде и уценке блока кода)
# example: BigBossManJeb
# %message%: содержимое сообщения
# пример: Hello!
# %primarygroup%: имя основной группы игрока
# %world%: названия мира, где сейчас находится игрок
# пример: world
# %worldalias%: псевдоним к названию мира игрока, используемый в Multiverse-Core
# пример: Mainland
# %date%: текущие время и дата
# пример: Sun Jan 1 15:30:45 PDT 2017
# %channelname%: имя канала, в которое было отправлено сообщение, если сообщение было отправлено в канал вообще
# пример: Global
# Также поддерживаются PlaceholderAPI шаблоны
#
MinecraftChatToDiscordMessageFormat: "**%primarygroup%** %displayname% » %message%"
MinecraftChatToDiscordMessageFormatNoPrimaryGroup: "%displayname% » %message%"
# Плагины для обработки канала чата
# Это специальное сообщение, которое используется только тогда, когда подключен поддерживаемый плагин канала чата
# Модифицирует внутри-игровые сообщения, добавляя туда полезную информацию
#
# Доступные шаблоны:
# %channelcolor%: цвет символов, соответствующий каналу
# пример: Если цвет данного канала чата - красный, то это превратится в &c
# %channelname%: символьное имя канала - техническое имя которое видно только серверу
# пример: staff
# %channelnickname%: формальный ник канала, который видят игроки
# пример: Staff
# %message%: сообщение после обработки посредством DiscordToMinecraftChatMessageFormat / DiscordToMinecraftChatMessageFormatNoRole
# пример: jeb_ > Hello from the server!
#
ChatChannelHookMessageFormat: "%channelcolor%[%channelnickname%]&r %message%"
# Dynmap сообщения
#
# DynmapNameFormat: формат ника, отправляемого в Dynmap (это может быть скрыто в зависимости от настроек dynmap)
# DynmapChatFormat: формат сообщения, отправляемого в Dynmap
#
# Доступные шаблоны:
# Те же, что в Discord -> Minecraft
#
# DynmapDiscordFormat: формат сообщений Dynmap, идущих в Discord
#
# Доступные шаблоны:
# %message%: содержимое сообщения
# пример: Hello!
# %name%: имя пользователя для сообщения, отправленного в веб-чате Dynmap (может быть пустым)
# пример: Notch
# Также поддерживаются PlaceholderAPI шаблоны
#
DynmapNameFormat: "[Discord | %toprolealias%] %username%"
DynmapChatFormat: "%message%"
DynmapDiscordFormat: "[Dynmap] %name% » %message%"
# Канал консоли Discord
# Формат вывода серверной консоли в канал консоли (если тот включён)
#
# Доступные шаблоны:
# {level}: тип логов
# пример: INFO, WARN, ERROR
# {name}: имя регистратора
# пример: Server
# {datetime}: текущие время и дата
# пример: Sun 15:30:45
# Также поддерживаются PlaceholderAPI шаблоны
#
# DiscordConsoleChannelPrefix: Префикс для добавления перед сообщениями журнала.
# DiscordConsoleChannelSuffix: Суффикс для добавления после сообщений журнала.
#
DiscordConsoleChannelTimestampFormat: "EEE HH:mm:ss"
DiscordConsoleChannelPrefix: "[{date} {level}{name}] "
DiscordConsoleChannelSuffix: ""
DiscordConsoleChannelPadding: 0
# Канал чата Discord, обработка ошибок команд !c
# Используется в случае нехватки у пользователя прав.
#
# Доступные шаблоны:
# %user%: имя пользователя, который пытался исполнить команду
# пример: Notch
# %error%: причина ошибки
# пример: no permission
#
DiscordChatChannelConsoleCommandNotifyErrorsFormat: "**%user%**, ты пытался исполнить команду. К сожалению, произошла ошибка: %error%"
# Канал чата Discord, команда отображающая список пользователей
# Сообщения, отправляемые при запросе списка текущих пользователей на сервере
#
# DiscordChatChannelListCommandFormatOnlinePlayers: сообщение перед списком пользователей
# DiscordChatChannelListCommandFormatNoOnlinePlayers: сообщение на случай, если в онлайне нет ни одного пользователя
# DiscordChatChannelListCommandPlayerFormat: формат вывода отдельного игрока в списке
# Доступные шаблоны:
# %username%: исходное имя игрока
# %displayname%: отображаемое имя игрока, по типу ника
# %primarygroup%: имя основной группы игрока
# %world%: название мира, в котором находится игрок
# %worldalias%: псевдоним к названию мира игрока, используемый в Multiverse-Core
# Также поддерживаются PlaceholderAPI шаблоны
# DiscordChatChannelListCommandAllPlayersSeparator: разделитель списка игроков
#
DiscordChatChannelListCommandFormatOnlinePlayers: "**Игроков онлайн (%playercount%):**"
DiscordChatChannelListCommandFormatNoOnlinePlayers: "**Нет никого онлайн**"
DiscordChatChannelListCommandPlayerFormat: "%displayname%"
DiscordChatChannelListCommandAllPlayersSeparator: ", "
# Minecraft -> Discord notification messages
#
#
# Вложенные свойства:
# Color: принимает шестнадцатеричный цветовой код (напр. "#ffffff") или целое число RGB (напр. 0)
# Fields: формат "заглавие;стоимость;inline" (e.c. "Кто присоединился?;%displayname%;true") или "пусто", чтобы добавить пустое поле
# Timestamp: установите значение true, чтобы использовать время, когда было отправлено, или использовать отметку времени эпохи (https://www.epochconverter.com/)
#
# Доступные заполнители для PlayerJoin/PlayerFirstJoin/PlayerLeave/PlayerDeath/PlayerAchievement:
# %displayname%: отображаемое имя игрока, по типу ника
# %username%: исходное имя игрока
# %displaynamenoescapes%: отображаемое имя игрока, по типу ника без экранирования формата Discord (для использования во встроенном коде и уценке блока кода)
# %usernamenoescapes%: исходное имя игрока без экранирования формата Discord (для использования во встроенном коде и уценке блока кода)
# %date%: текущие время и дата
# %embedavatarurl%: аватар пользователя
# %botavatarurl%: аватар бота
# %botname%: имя бота
# Также поддерживаются PlaceholderAPI шаблоны
#
# Доступные заполнители для PlayerJoin:
# %message%: сообщение о входе в игру (Так, как оно отображается в Minecraft)
#
MinecraftPlayerJoinMessage:
Enabled: true
Webhook:
Enable: false
AvatarUrl: "%botavatarurl%"
Name: "%botname%"
Content: ""
Embed:
Enabled: true
Color: "#00ff00"
Author:
ImageUrl: "%embedavatarurl%"
Name: "%username% присоединился"
Url: ""
ThumbnailUrl: ""
Title:
Text: ""
Url: ""
Description: ""
Fields: []
ImageUrl: ""
Footer:
Text: ""
IconUrl: ""
Timestamp: false
#
# Доступные заполнители для PlayerFirstJoin:
# %message%: сообщение о входе в игру (Так, как оно отображается в Minecraft)
#
MinecraftPlayerFirstJoinMessage:
Enabled: true
Webhook:
Enable: false
AvatarUrl: "%botavatarurl%"
Name: "%botname%"
Content: ""
Embed:
Enabled: true
Color: "#ffd700"
Author:
ImageUrl: "%embedavatarurl%"
Name: "%username% впервые присоединился к нашему серверу"
Url: ""
ThumbnailUrl: ""
Title:
Text: ""
Url: ""
Description: ""
Fields: []
ImageUrl: ""
Footer:
Text: ""
IconUrl: ""
Timestamp: false
#
# Доступные заполнители для PlayerLeave:
# %message%: сообщение о выходе из игры (Так, как оно отображается в Minecraft)
#
MinecraftPlayerLeaveMessage:
Enabled: true
Webhook:
Enable: false
AvatarUrl: "%botavatarurl%"
Name: "%botname%"
Content: ""
Embed:
Enabled: true
Color: "#ff0000"
Author:
ImageUrl: "%embedavatarurl%"
Name: "%username% отключился"
Url: ""
ThumbnailUrl: ""
Title:
Text: ""
Url: ""
Description: ""
Fields: []
ImageUrl: ""
Footer:
Text: ""
IconUrl: ""
Timestamp: false
#
# Доступные заполнители для PlayerDeath:
# %deathmessage%: сообщение о смерти (Так, как оно отображается в Minecraft)
# %world%: название мира, в котором умер игрок
#
MinecraftPlayerDeathMessage:
Enabled: true
Webhook:
Enable: false
AvatarUrl: "%botavatarurl%"
Name: "%botname%"
Content: ""
Embed:
Enabled: true
Color: "#000000"
Author:
ImageUrl: "%embedavatarurl%"
Name: "%deathmessage%"
Url: ""
ThumbnailUrl: ""
Title:
Text: ""
Url: ""
Description: ""
Fields: []
ImageUrl: ""
Footer:
Text: ""
IconUrl: ""
Timestamp: false
#
# Доступные заполнители для сообщений PlayerAchievement:
# %achievement%: сообщение о достижении (Так, как оно отображается в Minecraft)
# %world%: название мира, в котором находится игрок
# Также поддерживаются PlaceholderAPI шаблоны
#
MinecraftPlayerAchievementMessage:
Enabled: true
Webhook:
Enable: false
AvatarUrl: "%botavatarurl%"
Name: "%botname%"
Content: ""
Embed:
Enabled: true
Color: "#ffd700"
Author:
ImageUrl: "%embedavatarurl%"
Name: "%username% получил достижение %achievement%!"
Url: ""
ThumbnailUrl: ""
Title:
Text: ""
Url: ""
Description: ""
Fields: []
ImageUrl: ""
Footer:
Text: ""
IconUrl: ""
Timestamp: false
# Сообщения тем каналов
# Все эти опции нужны, чтобы автоматически устанавливать темы каналов чата и консоли,
# Наполняя их всевозможной серверной информацией
#
# ChannelTopicUpdater______ChannelTopicFormat: сообщение, которое будет установлено как тема канала, каждые X секунд
# ChannelTopicUpdater______ChannelTopicAtShutdownFormat: сообщение, которое будет установлено как тема канала, когда сервер выключен
#
# Доступные шаблоны:
# %playercount%: текущее число игроков
# %playermax%: максимальное число игроков
# %date%: текущая дата
# %totalplayers%: общее число игроков, когда-либо подключавшееся к серверу
# %uptimemins%: число минут с момента запуска DiscordSRV
# %uptimehours%: число часов с момента запуска DiscordSRV
# %motd%: описание сервера в меню выбора серверов
# %serverversion%: версия серверной платформы (например Spigot-1.9)
# %freememory%: свободная память в МБ, согласно данным JVM
# %usedmemory%: используемая память в МБ, согласно данным JVM
# %totalmemory%: общая память в МБ, согласно данным JVM
# %maxmemory%: максимально выделенная память в МБ, согласно данным JVM
# %freememorygb%: свободная память в ГБ, согласно данным JVM
# %usedmemorygb%: используемая память в ГБ, согласно данным JVM
# %totalmemorygb%: общая память в ГБ, согласно данным JVM
# %maxmemorygb%: максимально выделенная память в ГБ, согласно данным JVM
# %tps%: средний TPS сервера
# Также поддерживаются PlaceholderAPI шаблоны
#
ChannelTopicUpdaterChatChannelTopicFormat: "%playercount%/%playermax% игроков онлайн | %totalplayers% уникальных игроков | Сервер запущен уже %uptimemins% минут | Обновлено: %date%"
ChannelTopicUpdaterConsoleChannelTopicFormat: "TPS: %tps% | Mem: %usedmemorygb%GB исп/%freememorygb%GB своб/%maxmemorygb%GB макс | %serverversion%"
# AtServerShutdownFormats поддерживает только %totalplayers%, %serverversion%, & %date% / %time%
ChannelTopicUpdaterChatChannelTopicAtServerShutdownFormat: "Сервер отключён | %totalplayers% уникальных игроков"
ChannelTopicUpdaterConsoleChannelTopicAtServerShutdownFormat: "Сервер отключён | %serverversion%"
# Сообщения команды /discord
# Это сообщение отсылается игрокам, когда они выполняют команду "/discord". Рекомендуется сохранить такой же синтаксис, как ниже
# Используйте {INVITE} в качестве заполнителя для ссылки приглашения, которая необходима людям для присоединения к серверу Discord
# (Использует DiscordInviteLink, настроенный в config.yml)
#
DiscordCommandFormat: "&bПрисоединяйся к нам в Discord по ссылке {INVITE}&b. Иcпользуй \"/discord ?\" чтобы узнать больше"
# Нет формата сообщения разрешения
NoPermissionMessage: "&cУ вас нет прав выполнения такой команды."
# Неизвестное командное сообщение
UnknownCommandMessage: "&bТакой команды не существует!"
# Сообщения запуска/остановки сервера
# DiscordChatChannelServerStartupMessage: сообщение, отправляемое при старте сервера; оставьте пустым, чтобы отключить
# DiscordChatChannelServerShutdownMessage: сообщение, отправляемое при остановке сервера; оставьте пустым, чтобы отключить
#
DiscordChatChannelServerStartupMessage: ":white_check_mark: **Сервер успешно запущен**"
DiscordChatChannelServerShutdownMessage: ":octagonal_sign: **Сервер остановлен**"
# Сообщения мониторинга (детектор лагов)
#
# Служба мониторинга отслеживает состояние сервера с момента последнего исполненного тика
# В случае превышения заданного таймаута, отсылаются сообщения
#
# ServerWatchdogMessage: сообщение, которое будет отправлено в главный канал.
# вы можете упоминать пользователей, используя "<@USERID>", i.e. "<@12345678901234567890>"
# вы можете упоминать роли, используя "<@&ROLEID>", i.e. "<@&12345678901234567890>"; see console when discordsrv loads for role ids
# вы можете упоминать владельца сервера, используя "%guildowner%"
# вы можете вставить дату и время падения сервера в сообщение, используя %date%
# вы можете использовать ServerWatchdogTimeout в качестве заполнителя, используя %timeout%
# вы можете использовать заполнитель %timestamp% для использования в формате метки времени Discord
#
ServerWatchdogMessage: "<t:%timestamp%:R> %guildowner%, сервер не ответил через %timeout% секунд :fire::bangbang:"
# Сообщения привязки аккаунта
# Эти сообщения используются при связывании аккаунтов Discord и Minecraft
#
# Доступные шаблоны:
# UnknownCode/InvalidCode: %code%: одноразовый код, сгенерированный для пользователя, для привязки аккаунта
# %mention%: упоминание учетной записи Discord
# DiscordAccountLinked: %name%: имя игрока Minecraft, с которым связан аккаунт Discord
# %displayname%: отображаемое имя игрока Minecraft, с которым связан аккаунт Discord
# %uuid%: uuid игрока Minecraft, с которым связан аккаунт Discord
# %mention%: упоминание учетной записи Discord
# DiscordAccountAlreadyLinked: %uuid%: uuid Minecraft связанной учетной записи Minecraft пользователя
# %username%: имя пользователя Minecraft связанной учетной записи Minecraft пользователя
# %mention%: упоминание учетной записи Discord
# DiscordLinkedAccountRequired %message%: сообщение, которое пользователь не смог отправить, потому что они не были связаны
# CodeGenerated: %code%: одноразовый код, сгенерированный для пользователя, для привязки аккаунта
# %botname%: имя бота Discord
# MinecraftAccountLinked: %id%: идентификатор пользователя Discord, с которым была связана учетная запись Minecraft
# %username%: имя пользователя Discord, с которым была связана учетная запись Minecraft
# LinkedCommandSuccess: %name%: имя пользователя Discord в Discord, с которым была связана учетная запись Minecraft.
# UnlinkCommandSuccess: %name%: имя пользователя Discord в Discord, с которым была связана учетная запись Minecraft.
# MinecraftNobodyFound: %target%: ввод, который привел к отсутствию результатов
#
# Discord
UnknownCode: "Я не знаю такого кода, попробуйте снова."
InvalidCode: "Вы уверены, что это ваш код? Обычно код выглядит как 4 цифры."
DiscordAccountLinked: "Ваш Discord аккаунт был успешно привязан к Minecraft-аккаунту %name% (%uuid%)"
DiscordAccountAlreadyLinked: "Вы уже связаны с %username% (%uuid%)"
DiscordLinkedAccountRequired: "Вы попытались отправить сообщение в игровой чат из клиента Discord, однако сервер требует, чтобы вы привязали ваш Майнкрафт аккаунт к вашей учётной записи Discord. Чтобы связать эти аккаунты, используйте команду `/discord link` в игре. \n```%message%```"
DiscordLinkedAccountCheckFailed: "Не удалось проверить, связан ли ваш аккаунт, повторите попытку позже."
# Minecraft
CodeGenerated: "Ваш привязочный код - %code%. Отправьте личное сообщение боту (%botname%) с этим кодом, чтобы привязать свой аккаунт."
ClickToCopyCode: "Нажмите, чтобы скопировать"
MinecraftAccountLinked: "&bВаш UUID был связан с пользователем Discord %username% (%id%)"
MinecraftAccountAlreadyLinked: "&bВаш Майнкрафт аккаунт уже связан с учётной записью Discord. Вы можете отвязать его командой /discord unlink, если у вас есть соответсвующие права."
LinkedCommandSuccess: "&bВаш Майнкрафт аккаунт успешно связан с %name%."
UnlinkCommandSuccess: "&bВаш Майнкрафт аккаунт больше не связан с %name%."
MinecraftNoLinkedAccount: "&cВаш Майнкрафт аккаунт не привязан к аккаунту Discord."
LinkingError: "&cК сожалению, мы не можем связать ваши аккаунты из-за внутренней ошибки. Свяжитесь с администратором сервера."
MinecraftNobodyFound: "&cНикого с такими Discord ID/Discord ник/Minecraft ник/Minecraft UUID подходящего \"%target%\" не найдено."

View File

@ -0,0 +1,54 @@
# Синхронизация никнеймов
# Can be controlled per player through the use of the 'discordsrv.nicknamesync' permission (granted by default)
#
# В Discord будет такой же ник, как в Minecraft
# NicknameSynchronizationEnabled: Включить - true, отключить - false
# NicknameSynchronizationCycleTime: Время (в минутах) - как часто DiscordSRV будет синхронизировать ники игроков.
# NicknameSynchronizationFormat: Формат ников в дискорде.
# Примеры:
# %displayname%: отображаемое имя игрока
# %username%: имя пользователя игрока
# %discord_name%: логин игрока в Discord
# %discord_discriminator%: дискорд-дискриминатор игрока
# Поддерживает шаблоны из PlaceholderAPI.
#
NicknameSynchronizationEnabled: false
NicknameSynchronizationCycleTime: 3
NicknameSynchronizationFormat: "%displayname%"
# Синхронизация групп в Minecraft и ролей в Discord
# Требует установку плагина Vault
#
# GroupRoleSynchronizationGroupsAndRolesToSync: Группы и роли, которые нужно синхронизировать
# Используйте формат {"группа": "id роли в Discord"}
# Чтобы узнать id роли, напишите "/discord debug" и посмотрите в первую секцию.
# GroupRoleSynchronizationMinecraftIsAuthoritative: Если выдать/забрать группу в Minecraft, то должна ли соответствующая роль
# появиться/пропасть в Discord? true - да, false - нет
# GroupRoleSynchronizationOneWay: whether to synchronise only one way, the way it is synchronised depends on the value
# of GroupRoleSynchronizationMinecraftIsAuthoritative.
# GroupRoleSynchronizationEnableDenyPermission: Включены ли в Minecraft права discordsrv.sync.deny.<id роли>
# GroupRoleSynchronizationPrimaryGroupOnly: true - синхронизируется только главная группа игрока.
# false - синхронизируются все побочные и родительские группы.
# GroupRoleSynchronizationOnLink: Нужно ли проводить синхронизацию, когда игрок привязывает аккаунт в Discord?
# GroupRoleSynchronizationCycleTime: Время (в минутах) - как часто DiscordSRV будет синхронизировать роли и группы игроков.
# GroupRoleSynchronizationCycleCompletely: должна ли синхронизация, запущенная по таймеру, синхронизировать каждого участника на серверах Discord ботов
#
GroupRoleSynchronizationGroupsAndRolesToSync: {"player": "1371491528786182216"}
GroupRoleSynchronizationMinecraftIsAuthoritative: true
GroupRoleSynchronizationOneWay: false
GroupRoleSynchronizationEnableDenyPermission: false
GroupRoleSynchronizationPrimaryGroupOnly: false
GroupRoleSynchronizationOnLink: true
GroupRoleSynchronizationCycleTime: 5
GroupRoleSynchronizationCycleCompletely: false
# Синхронизация банов
# Если игрока забанят в Minecraft, то он автоматически получит бан в дискорде (и наоборот)
#
# BanSynchronizationDiscordToMinecraft: Если игрока забанили в Discord, нужно ли банить его в Minecraft? true - да, false - нет
# BanSynchronizationDiscordToMinecraftReason: С каким сообщением банить игрока в Minercaft, если его забанили в Discord
# BanSynchronizationMinecraftToDiscord: Если игрока забанили в Minecraft, нужно ли банить его в Discord? true - да, false - нет
#
BanSynchronizationDiscordToMinecraft: false
BanSynchronizationDiscordToMinecraftReason: "&cВы были заблокированы на сервере Discord, поэтому ваш аккаунт в Minecraft тоже получил бан."
BanSynchronizationMinecraftToDiscord: false

View File

@ -0,0 +1,29 @@
# Это конфиг для интеграции голосового чата через DiscordSRV.
# Голосовой чат - экспериментальная функция. Некоторые вещи могут работать неправильно.
# Просим вас сообщать в дискорд обо всех ошибках, связанных с этим модулем:
# https://discordsrv.com/discord
# Включить голосовой модуль? true - вкл., false - выкл.
# После изменения этого параметра необходимо перезагрузить сервер.
Voice enabled: false
# Количество тиков между обновлениями (1 секунда - 20 тиков)
Tick speed: 5
# Главная категория, в которой будут создаваться/удаляться/перемещаться голосовые каналы
# В этой категории не должно быть никаких каналов, кроме лобби (см. ниже)
Voice category: 000000000000000000
# Канал-лобби, в который будут попадать игроки, находящиеся слишком далеко от других (те, кому не с кем общаться)
# Чтобы подключиться к голосовому чату, игрокам нужно будет зайти в этот канал.
Lobby channel: 000000000000000000
# Если у кого-то есть права на обход ограничения на разговоры в лобби, то всё равно глушить его? true - да, false - нет
Mute users who bypass speak permissions in the lobby: true
Network:
# Расстояние, на котором игроки могут говорить друг с другом
Vertical Strength: 40
Horizontal Strength: 80
# Если игрок вошёл в зону, то, чтобы выйти из неё, ему нужно отойти назад на большее расстояние
# То, насколько больше это расстояние - определяется этой настройкой
Falloff: 5
# Whether voice network channels are visible to everyone, even those not connected
# Helps let players know if people are actually using the voice network at the moment
Channels are visible: false

BIN
plugins/ImageFrame-1.8.4.0.jar (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,190 @@
Messages:
Reloaded: '&eImageFrame has been reloaded!'
ImageMapProcessing: '&eImageMap is being processed, please wait!'
# Leave this empty ("") to disable action bar message
ImageMapProcessingActionBar: '&eImageMap &a{Name} &eis being processed{Dots}'
# Leave this empty ("") to disable action bar message
ImageMapQueuedActionBar: '&7ImageMap &a{Name} &eis currently queued ({Position} Remaining)'
ImageMapCreated: '&aImageMap has been created!'
ImageMapRefreshed: '&aImageMap has been refreshed!'
ImageMapDeleted: '&eImageMap had been deleted!'
ImageMapRenamed: '&aImageMap had been renamed!'
ImageMapTogglePaused: '&aToggled ImageMap playback pause!'
ImageMapPlaybackJumpTo: '&aJumped to position at {Seconds} seconds!'
ImageMapPlayerPurge: '&ePurged {Amount} ImageMaps owned by {CreatorName} ({CreatorUUID}) - [{ImageMapNames}]'
SetCreator: '&aImageMap creator of id {ImageID} set to {CreatorName} ({CreatorUUID})'
InvalidOverlayMap: '&cOverlay only works on Vanilla Minecraft maps and without duplicates in selection!'
ImageMapAlreadyQueued: '&cYou already have another ImageMap queued and processing, please wait!'
UnableToLoadMap: '&cImageMap cannot be loaded, there is a problem while reading the image. Contact server administrators to check the server console for more info.'
UnableToChangeImageType: '&cChanging the image type is currently not supported. Please create a new image map instead.'
UnknownError: '&cAn unknown error had occurred.'
ImageOverMaxFileSize: '&cImageMap cannot be loaded as it is over the max file size allowed. ({Size} bytes)'
NotAnImageMap: '&cThat is not an ImageMap'
UploadLink: '&aOpen {URL} on your browser to upload an image, it is valid for 5 minutes.'
UploadExpired: '&cImage upload link had expired, please create a new one.'
URLImageMapInfo:
- '&bImageID: {ImageID}'
- '&aName: {Name}'
- '&eMap Size: {Width} x {Height}'
- '&6Dithering: {DitheringType}'
- '&dCreator: {CreatorName} ({CreatorUUID})'
- '&fAccess: {Access}'
- '&aTime Created: {TimeCreated}'
- '&bMarkers: {Markers}'
- '&eURL: {URL}'
NoPermission: '&cYou do not have permission to do that!'
NoConsole: '&cThis command can only be ran by players!'
PlayerNotFound: '&cThis player cannot be found!'
InvalidUsage: '&cInvalid Usage!'
NotEnoughMaps: '&cYou do not have {Amount} maps!'
Oversize: '&cThat is too big! Max size for a map is {MaxSize}'
URLRestricted: '&cThat URL is restricted and cannot be used to create image maps.'
PlayerCreationLimitReached: '&cYou can only create {Limit} maps at once! Delete some to create new ones'
DuplicateMapName: '&cYou''ve already created an image map with that name!'
MapLookup: '&bList of image maps by {CreatorName} ({CreatorUUID}):'
ItemFrameOccupied: '&cFailed to place or remove some maps on selected ItemFrame, they are either destroyed, replaced, occupied or protected.'
NotEnoughSpace: '&cUnable to place Combined ImageMap as there is not enough room.'
InvalidImageMap: '&cThis image map had likely already been deleted.'
GivenInvisibleFrame: '&aGiven {Amount} invisible item frames to {Player}.'
AccessPermission:
Updated: '&aUpdated access for {PlayerName} ({PlayerUUID}), they now have {Permission} permission.'
Types:
NONE: NONE
GET: GET
MARKER: MARKER
EDIT: EDIT
EDIT_CLONE: EDIT WITH CLONE
ALL: ALL
Selection:
Begin: '&bRight click an Item Frame to select corner 1 and 2'
Clear: '&eLeaving selection mode'
Corner1: '&aSelected Item Frame corner 1'
Corner2: '&aSelected Item Frame corner 2'
Invalid: '&cInvalid selection!'
Oversize: '&cOversize selection! Max size for a map is {MaxSize}'
Success: '&aSelected {Width} x {Height} Item Frames! &eIf any of them are removed/replaced, you will need to select them again.'
NoSelection: '&cYou don''t have a valid selection yet.'
IncorrectSize: '&cYour selection''s size does not match, {Width} x {Height} required.'
Markers:
AddBegin: '&aRight click on an Item Frame containing the map "{Name}" to place marker! &bRun "/imageframe marker cancel" to cancel placement'
AddConfirm: '&aMarker placed!'
Remove: '&eMarker removed!'
Clear: '&eMarkers cleared!'
Cancel: '&eMarker placement cancelled!'
DuplicateName: '&cThere is already a marker with that name!'
NotAMarker: '&cThat is not a valid marker'
NotRenderOnFrameWarning: '&eWarning: This marker type does not render on Item Frames!'
LimitReached: '&cYou can only create {Limit} markers on one map!'
# Date format used where a time based variable is displayed
DateFormat: dd/MM/yyyy HH:mm:ss zzz
Preferences:
Keys:
VIEW_ANIMATED_MAPS: View Animated Maps
Values:
'TRUE': '&aEnabled'
'FALSE': '&cDisabled'
UNSET: '&7Unset'
UpdateMessage: '&ePlayer Preference {Preference}&e has been updated to {Value}&e!'
Settings:
MapItemFormat: '&f{Name} &7({X}, {Y})'
# Whether empty maps are required to create image maps when not in creative
RequireEmptyMaps: true
# Max size of an image map
MaxSize: 30
# When enabled, Only websites from the list below is allowed to be shown through in-game maps
RestrictImageUrl:
Enabled: false
Whitelist:
- https://i.imgur.com
- http://i.imgur.com
- https://storage.googleapis.com
- http://storage.googleapis.com
- https://cdn.discordapp.com
- http://cdn.discordapp.com
- https://media.discordapp.net
- http://media.discordapp.net
- https://textures.minecraft.net
- http://textures.minecraft.net
# If the image is larger than the defined size, it won't be downloaded for preview
# (In Bytes)
MaxImageFileSize: 30000000
# If an image takes more than this time to load, it will be rejected
# (In Seconds)
MaxProcessingTime: 60
# How many images should be processed in parallel
# Updating this option requires a server restart
ParallelProcessingLimit: 1
# Max amount of image maps a player in the following groups can create
# Setting -1 means unlimited
# To add a player to a group, give the permission "imageframe.createlimit.<group>"
# For example "imageframe.createlimit.vip"
# Players with no groups will be treated as "default" unless they have "imageframe.createlimit.unlimited"
PlayerCreationLimit:
default: 10
vip: 15
moderator: 20
# Max amount of markers on an individual map
MapMarkerLimit: 20
CombinedMapItem:
Name: '&bImageMap &f- &f{Name} &7({Width} x {Height})'
Lore:
- '&aRight Click on Item Frames of size {Width} x {Height} to place ImageMap'
- ''
- '&7ImageID: {ImageID}'
- '&7Creator: {CreatorName} ({CreatorUUID})'
- '&7Time Created: {TimeCreated}'
# How many map packets can be sent to a player in 1/20 of a second
# You can turn this down if you are facing network issues
# However maps might take longer to show to a player
# To disable the rate limit, set to -1
MapPacketSendingRateLimit: -1
# Exempt certain map ids from deletion if their ImageFrame map is deleted
# Values can be map ids (For example: "13") or ranges (inclusive) of map ids (For example: "10-13")
ExemptMapIdsFromDeletion:
- '-1'
# This option should only be useful to developers and people who knew what they are doing
MapRenderersContextual: false
# Changing this option requires a restart
HandleAnimatedMapsOnMainThread: false
SendAnimatedMapsOnMainThread: false
# Valid modes are "DYNAMIC" and "MANUAL_PERSISTENT"
# DYNAMIC: load and unload image cache depending on whether a player is viewing
# May use more CPU and image might appear with a slight delay
# MANUAL_PERSISTENT: image cache stay loaded from server start
# May use more memory
# Changing this setting requires a restart
CacheControlMode: DYNAMIC
# Set this to true if you have corrupted 0 size map data in the world folder (not the ImageFrame plugin folder)
# Set this to false if your system's file IO is slow
TryDeleteBlankMapFiles: false
# ImageFrame's convenient upload system where you can upload directly through an embedded web server
UploadService:
# Changing this value requires a restart
Enabled: false
# This is only used for displaying to the end user
DisplayURL: http://change.this.to.your.server.ip.in.the.config
WebServer:
# Address in which the webserver binds to, defaults to 0.0.0.0
# Use 127.0.0.1 to limit to local access
# Changing this value requires a restart
Host: 0.0.0.0
# Port in which the webserver is hosted, make sure it is not blocked by your firewall
# Changing this value requires a restart
Port: 8517
# ImageFrame's built in survival friendly way of making invisible item frames
InvisibleFrame:
# Survival friendly way to get invisible item frames by splashing dropped items with invisibility potions
# Set to -1 for unlimited
# Set to 0 to disable
MaxConversionsPerSplash: 8
# Should empty invisible item frames glow
# Existing frames are not updated until they are interacted with
GlowEmptyFrames: true
Hooks:
ViaVersion:
# Enable this if your players below 1.13 is having network issues
DisableSmoothAnimationForLegacyPlayers: false
# Enable update notifications for admins
Updater: true

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,59 @@
{
"type": "com.loohp.imageframe.objectholders.URLStaticImageMap",
"index": 0,
"name": "fdfd",
"url": "https://cdn.discordapp.com/attachments/1371494748854030437/1384225931173826721/image_proxy.jpg?ex\u003d686ea95b\u0026is\u003d686d57db\u0026hm\u003de9b4feec38d3ba7f87a3da4a14e0c52ab478061a29e4337216108da905010c95\u0026",
"width": 3,
"height": 3,
"ditheringType": "nearest-color",
"creator": "40427344-abb4-359c-9e1c-4a5d67f3a3a2",
"hasAccess": {},
"creationTime": 1752051597001,
"mapdata": [
{
"mapid": 0,
"image": "0.png",
"markers": []
},
{
"mapid": 1,
"image": "1.png",
"markers": []
},
{
"mapid": 2,
"image": "2.png",
"markers": []
},
{
"mapid": 3,
"image": "3.png",
"markers": []
},
{
"mapid": 4,
"image": "4.png",
"markers": []
},
{
"mapid": 5,
"image": "5.png",
"markers": []
},
{
"mapid": 6,
"image": "6.png",
"markers": []
},
{
"mapid": 7,
"image": "7.png",
"markers": []
},
{
"mapid": 8,
"image": "8.png",
"markers": []
}
]
}

View File

View File

@ -0,0 +1,6 @@
{
"uuid": "40427344-abb4-359c-9e1c-4a5d67f3a3a2",
"preferences": {
"viewAnimatedMaps": "unset"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

View File

@ -0,0 +1,262 @@
<!--
~ This file is part of ImageFrame.
~
~ Copyright (C) 2025. LoohpJames <jamesloohp@gmail.com>
~ Copyright (C) 2025. Contributors
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ImageFrame Upload</title>
<link href="https://fonts.cdnfonts.com/css/minecraftia" rel="stylesheet">
<link rel="icon" type="image/x-icon" href="imageframe.png">
<style>
* {
font-family: 'Minecraftia', sans-serif;
}
body {
display: block;
justify-content: center;
align-items: center;
height: 90vh;
min-height: 90vh;
text-align: center;
background-image: url("background.webp");
}
.title {
color: white;
margin-bottom: 0;
margin-top: 30px;
}
.expire {
margin: 0;
font-size: 14px;
color: #AAAAAA;
}
.name {
color: #FFFF55;
}
.container {
margin: 30px auto 30px auto;
height: 80%;
text-align: center;
background: #D2BF82;
padding: 20px;
border-radius: 10px;
aspect-ratio: 1;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.drop-zone {
width: 100%;
height: calc(100% - 45px);
background: #A25430;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
margin-bottom: 12px;
cursor: pointer;
position: relative;
overflow: hidden;
color: white;
box-shadow: inset 0 0 3px black;
}
.drop-zone img {
max-width: 100%;
max-height: 100%;
display: none;
position: absolute;
object-fit: cover;
}
button {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMQAAAAPCAAAAACe4j/AAAAEuElEQVRIx1WWS5Ibuw5EtddrdRRJJE4iSKrb4c2/AUuy30iK+jEBHCTwAICMCgAKiGhKVQUwKzJHQo4mQGBy7AIvk1E2AQKhFt6bUGD1gILy0DkD4dmzACkGyzCScgFgQmLZr4LpQpC56QB2wgSYE8i1fd6xd1yPHIAKwAs14Undx2LIHK0X6vdFbzTa6CNBLQE8Y5rapn7oAl3KSDKC6cLfL6sLnIVG7ffnyUgvQ6rwLjUZdIVqWz0iEXXCZ+TJsV8feUdoPHDk+a/IeAbq0ldLT59jtHweHwmKS6gFSUYCqKcVsPami1pEnqolkCMBiAS87FXTICp03geYUr8TV8un3KuyC0BfTUzihOCdwjUya1bkT9VWe+AaFOoJzHdtERXRe/eulyEDhC6pjYwr+JQuIDU9/0wQBnJEAkd+9i6IRTJrV7YWnGfwLA6ESphkBoCu88M0YH1CTTOiRUpDdwpGkkP5yL9phhwn+QVxDarAXq513y9bLKgxBGR/CjDyMl4ECd6lO82CaMLbEHGHp1R8ePDERj392ssaCOigNjJ+dXXl6OLUFfVx6dA1BFJLlHpkUHPam095C3QJLIjn6OLIOB3xe0JS85Zd+govg1/z/UhtG3RdVW98yxNp5I0Vtf/U+6y/dJ/yHtSK4q7G9ARscC3/Df/kXTwiT3d6ovjEISLJIVEvBwWeCXlALZTbpy85xqWuf3sNiBBUmYjI+BqN6aNQqDWpipSYf3W1nOV/WALoykjIiCPreSn97UigsjZdPA5s3AmCDIxaVO0Fa1fV/qkaiijPPz/bEeRyLSBDI8K8j37TO8aH7vmOqUUQ1DboYhvqd+FlFGEo+2T75MbLGnjvPeu7Pl521Ap14dcR3h7p75qv4xieqnNDoyCPLt/yKkf5gOUXl+6S3d9Syq/982fz+fhpsm28C5EhJcxsWWQke6KoPMA7tqm7kKcrn6FLhWcoqCNCxDPyQ8wEKR73nIlEX8GpARSJX7/rzeNtWPD/Dl2IwtOYMwV7osGsHYJanzeU7KqIZVCTcrT0IEbyD4d1e1dkBtW2qLhLXK7a1ogDqsjI1DR4PY7nHEqfF9tn8HUJL+eQ/lGOXdwI1++57CqgmDaReM9CZYLAk4D4ymqti4KZI9Htz9OnrcuOhCQEqJfXaxHPAFG/l/ee1GFJPXmPryYUiUGPutnRGXkagmnjHk5RNpm7xxiclm6CjJEQ4+MD4xPmuT9Ef4b3YT3B51a7d4Np76PF0cavuC+SoaH6PlilipEakoJBJETWT3k7Hf+1REPj2fIx95t5ct6u9S5v3KM2fv2Ve29ax9yC98zT2IZot61MHyYtdPF92nguZ29xfcVxSu9Nj5Gl8G3wcVoW8n1Q/f6BHFEAyy5R2aRIdYH8XfV4453vHKcnqarXPD6mdrD0rlVV5xBPF2xuJM5Oo0SdaaqGMjJva7ii6bYv74IzPMo5pGebpu72ghypwTR+WWDuhQOkFijGyAzF3GXh11lEH0hkPINZivpTqLEtVm2j1hVcn/S0//q0es5dbyxOErxKivQ+bHotvzcT3/XztPf20XqG6fJZMePT2X6ts+nlm9LoSYHMiHuJjGXniB7v2fo/5qT4nuxYg6AAAAAASUVORK5CYII=);
border-color: #AAA #565656 #565656 #AAA;
padding: 7px 20px;
font-size: 15px;
cursor: pointer;
text-shadow: 3px 3px #4C4C4C;
outline: 2px solid #000;
color: white;
}
button:hover:enabled {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMQAAAAPCAMAAACMV5AuAAAAVFBMVEVtd7ZteLZverdwerdwe7hxfLhyfbl0frl1f7p2gLt4grx6hLx7hb18hr5+iL+AisCBi8GCjMGEjsKGkMOHkcSIksSKk8WLlMWLlcaMlcaNlsePmMdwBHmVAAAEjElEQVRIx1WW27YbKw5F3Ul2GYTWFAJX+pyd///PfgDsTg0/mSqQ1k08AEAeDkAA7kXyDAeyu2QCWREgCGSvAAbIE/D9U2m8Ji4Drw0CEhP7EMiqBFxmDMBEkHvd5AziDsjoCKQXddUl1nuZgMZrf0PMdj1kgNY+Ay+CJPg8kj1rR3X/GS9kxaoJVFaB6QkxIX5TBX65mpAZGQH3HaoCFMj6/GxuYgDyTsyup1hfxwxVN+F08ANGANyf8jqAPaBpranJvhxV+VV08JGPVScmcL8W4EIuAFWFHMZrUkUfNC3WtIsEaFogMWJRl839MES61w1cjMUsI1fb7GKaoENMOdFNykzXPz2mlwekkXjV4ioO9b15rZWZd4AaCL9cxdSutl8buIOUkd8JTgAy01IKoFoFPhAZr65SbDHgxFIGKi5IpLaKdlafAHxaVWDt2SSZ24LQhEx6aLGyj7RtELDLiA7EiD72ehBiQJo5oPq1nOQMYGAIYoY2AwIrImaA+25P8vZRa0KgqrjnQIaACiom/1G9Sla3GUHVLl/mMl/mxeUPGT0T5seAeeAQtF9WV2F7cX4niJ4DYmBd12oh7jymyRkBuq6M81mQuExHVv313beo9VH3ojfM2zZ8AkTG8X7EeDs6OZw+mrY7E5l/gqQJmZx+YySQAi1/dqQZy0as4FL1d7nrcfd1kjWTX1ZIYESTUCnuPZE7+anrqcxlz3diUX2HowHCf15S3AvxrnhRxeMwtQACGYGKZ7wGjNl7vH73MHdP8s/vSXM0FiRqMnPowfbjRsfe6n7nZ/FGIyfgF6+A/t1XTrcWB3Q42AxkMOfMfuJotRPgqGqFMfB8KO6eN+BEpO8F2eLZ18YO0GUdmEDcXMcNey+XuOfvP5P35guSVxAzWRYUpIoSuZiJrJ/p4zPouw0pwX+6XwpIcyNWEcJ/uf5Svuyx+ncTfhmotEhIBPe/8f961F/jI5aQfSs3WFOwChnZZxPk+HQjZu/WBuDFVwobZnoLISBOdkmNLFPE9iadiImsgTcdTDKA8dj1qBT518Xcg6+6L0Yl/nqCLeH+b46InkCSETTBzEQBRoPEwS9lKVUkpEx426M3oIMHYQLhK/B6jHvgXw6if4+YM4mlJdWDpLw4MhHgjwBZgIt+ZJdAVENOEkiv6mY4yy5nFPjnQmGfGVy0IqP+cmbsWF7Se/rT+5ZBzHPdKfajHW2ouWldPJaoTDJ3GUYTNMV/IyaiPYqQuX0VPXK+ra3Mc8c5Wlkp4D/e5S5htjXU3HnPPJsBXraRM/rSpOMX99zMoVradRl9AMxJdVPIYgf8Rhu0DvLM739A5rmjJ51QcW9SFXjcvR85oYOhSKTsd65pqdKWIV59ZO/7kKTDJLbvYw9XVRIyTXKJdfm4rOjE18yT8IHM/euZa0Z0fLvBSIh7h925QLoXR80WNfnqOHHP7Qk5aj+dTLX4E3hhIkafoGd15/IDT/lPTVSVr233dy6OkJtiLm0yBu+byeE2Yc59pVrDdKyPjxgD4h6r6vcFwpYNHMxVBaE2ApmfyTTjf5jQnWRymG7iAAAAAElFTkSuQmCC);
border-color: #BDC6FF #59639A #59639A #BDC6FF;
}
button:disabled {
cursor: not-allowed;
filter: brightness(0.5);
}
.closed-container {
text-align: center;
height: 100%;
align-content: center;
}
.closed-icon {
width: 120px;
}
.success-title {
color: #55FF55;
margin: 10px;
}
.error-title {
color: #FF5555;
margin: 10px;
}
@media screen and (max-width: 700px) {
.container {
aspect-ratio: unset;
}
}
</style>
</head>
<body>
<h2 class="title">ImageFrame Upload<label id="titlePlayer"></label></h2>
<p class="expire" id="expire">This link expires in ...</p>
<div class="container" id="container">
<div class="drop-zone" id="dropZone">
Drop image here or click to select
<img id="imagePreview" alt="Image Preview" src="">
</div>
<input type="file" id="fileInput" accept="image/png, image/jpeg, image/gif" hidden>
<button id="uploadBtn" disabled>Upload</button>
</div>
<script>
const urlParams = new URLSearchParams(window.location.search);
const user = urlParams.get('user');
const uploadId = urlParams.get('id');
const player = urlParams.get('player');
const expire = urlParams.get('expire');
function showExpired() {
const forPlayer = player ? ` for <span class="name">${player}</span>` : "";
document.body.innerHTML = `
<div class="closed-container">
<img src="imageframe.png" alt="ImageFrame" class="closed-icon">
<h2 class="error-title">This link${forPlayer} had expired!<br>Please create a new one in-game.</h2>
</div>
`;
}
function showError() {
const forPlayer = player ? ` for <span class="name">${player}</span>` : "";
document.body.innerHTML = `
<div class="closed-container">
<img src="imageframe.png" alt="ImageFrame" class="closed-icon">
<h2 class="error-title">There is an error while uploading${forPlayer}.<br>Please create a new one in-game.</h2>
</div>
`;
}
function showSuccess() {
const forPlayer = player ? ` for <span class="name">${player}</span>` : "";
document.body.innerHTML = `
<div class="closed-container">
<img src="imageframe.png" alt="ImageFrame" class="closed-icon">
<h1 class="success-title">Upload successful${forPlayer}!<br>Please continue in-game!</h1>
</div>
`;
}
if (player) {
document.getElementById('titlePlayer').innerHTML = ` for <span class="name">${player}</span>`;
}
if (expire) {
const element = document.getElementById('expire');
const taskId = setInterval(() => {
const now = Date.now();
const diff = Math.floor((expire - now) / 1000);
if (diff < 0) {
clearInterval(taskId);
showExpired();
return;
}
const minutes = Math.floor(diff / 60);
const seconds = (diff % 60).toString().padStart(2, '0');
element.innerHTML = minutes > 0 ? `This link expires in ${minutes}m ${seconds}s` : `This link expires in ${seconds}s`;
}, 500);
}
const dropZone = document.getElementById("dropZone");
const fileInput = document.getElementById("fileInput");
const uploadBtn = document.getElementById("uploadBtn");
const imagePreview = document.getElementById("imagePreview");
let selectedFile = null;
dropZone.addEventListener("click", () => fileInput.click());
fileInput.addEventListener("change", handleFileSelect);
dropZone.addEventListener("dragover", (e) => {
e.preventDefault();
dropZone.classList.add("highlight");
});
dropZone.addEventListener("dragleave", () => dropZone.classList.remove("highlight"));
dropZone.addEventListener("drop", (e) => {
e.preventDefault();
dropZone.classList.remove("highlight");
if (e.dataTransfer.files.length) {
handleFileSelect({ target: { files: e.dataTransfer.files } });
}
});
function handleFileSelect(event) {
const file = event.target.files[0];
if (file && ["image/png", "image/jpeg", "image/gif", "image/webp"].includes(file.type)) {
selectedFile = file;
uploadBtn.disabled = false;
const reader = new FileReader();
reader.onload = function(e) {
imagePreview.src = e.target.result;
imagePreview.style.display = "block";
};
reader.readAsDataURL(file);
} else {
alert("Only PNG, JPG, and GIF files are allowed.");
fileInput.value = "";
selectedFile = null;
uploadBtn.disabled = true;
imagePreview.style.display = "none";
}
}
uploadBtn.addEventListener("click", () => {
if (!selectedFile) return;
const formData = new FormData();
formData.append("image", selectedFile);
fetch(`/upload?user=${user}&id=${uploadId}`, {
method: "POST",
body: formData
})
.then(response => response.json())
.then(data => {
if (data.hasOwnProperty("error")) {
showError();
console.log("Upload failed: " + data.error);
} else {
showSuccess();
console.log("Upload successful: " + data.message);
}
})
.catch(error => {
showError();
console.log("Upload failed: " + error);
});
});
</script>
</body>
</html>