mirror of
https://codeberg.org/Andre601/AdvancedServerList.git
synced 2026-11-08 10:15:26 -05:00
Compare commits
132
Commits
v1.0.0-pre2
...
v1.6.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85e41b6c7e | ||
|
|
a220efc624 | ||
|
|
ea8871ce8f | ||
|
|
ea0fdc3798 | ||
|
|
1188ab0c9c | ||
|
|
aaefd4c928 | ||
|
|
940bf2fb9d | ||
|
|
0c24bf8d24 | ||
|
|
564ce7a820 | ||
|
|
bb8cd21b86 | ||
|
|
2d2d8a6175 | ||
|
|
fcd4bdbe14 | ||
|
|
3a9b2a7c5a | ||
|
|
3b3793ab9a | ||
|
|
d679694d6e | ||
|
|
47405f7492 | ||
|
|
af7408dcd5 | ||
|
|
17d0930195 | ||
|
|
91cd3b6032 | ||
|
|
2d67145ae5 | ||
|
|
ba1dd8a70d | ||
|
|
4ea77f2907 | ||
|
|
7fdc23baa1 | ||
|
|
d630b472ca | ||
|
|
99509b538b | ||
|
|
4539fe4628 | ||
|
|
8c81f4f5c8 | ||
|
|
f34ef3fbe4 | ||
|
|
45f68294c1 | ||
|
|
f4056e51ef | ||
|
|
7f38c0f224 | ||
|
|
17a4ba0f8c | ||
|
|
5cb1245126 | ||
|
|
0963d9ffb4 | ||
|
|
6dedd9368f | ||
|
|
f2df3727a7 | ||
|
|
2b7c24daa4 | ||
|
|
1e042461ac | ||
|
|
599c2db2bc | ||
|
|
87505f820c | ||
|
|
28109c8b5b | ||
|
|
243854592d | ||
|
|
4648bc30e9 | ||
|
|
f9a96e5525 | ||
|
|
d158fb852f | ||
|
|
77f95900e2 | ||
|
|
912fec1875 | ||
|
|
dba9ca20a4 | ||
|
|
7b94ae52db | ||
|
|
6d3bf50278 | ||
|
|
8039088fb9 | ||
|
|
ecaaf7bbf3 | ||
|
|
dd970cfabf | ||
|
|
a888481674 | ||
|
|
ee68eafc63 | ||
|
|
f22313a5c8 | ||
|
|
9603155722 | ||
|
|
df938485b2 | ||
|
|
0ddda8bd78 | ||
|
|
56a83e88fb | ||
|
|
1947f627ef | ||
|
|
3c344f9a5d | ||
|
|
8e2004cb81 | ||
|
|
004d723c81 | ||
|
|
90fb6a2654 | ||
|
|
0eb5daac81 | ||
|
|
f23f282ba9 | ||
|
|
df705c0c14 | ||
|
|
f27202f2df | ||
|
|
0d84335db9 | ||
|
|
50f878e39c | ||
|
|
b88ee87c96 | ||
|
|
a5f6e689f0 | ||
|
|
dd0bc8a43a | ||
|
|
563362504f | ||
|
|
bd95be080e | ||
|
|
2d02d48d3c | ||
|
|
15f7b5def3 | ||
|
|
f37813d5b7 | ||
|
|
93c2dda56b | ||
|
|
55f5132b37 | ||
|
|
f1e48c2a9c | ||
|
|
de01db4c12 | ||
|
|
eefb2b44dd | ||
|
|
799d06dee1 | ||
|
|
b9338a43e0 | ||
|
|
c89c5f0b49 | ||
|
|
1fac910ca1 | ||
|
|
69061f1a75 | ||
|
|
0d93dcf00d | ||
|
|
bb2828e47d | ||
|
|
cdcc872f3a | ||
|
|
f9192001ba | ||
|
|
0bd92862db | ||
|
|
773fbb55c3 | ||
|
|
ad4c69a269 | ||
|
|
b7a2599178 | ||
|
|
bd279d3673 | ||
|
|
5882372ce6 | ||
|
|
55d74f1abe | ||
|
|
0056a0e958 | ||
|
|
06396a1622 | ||
|
|
8d7df60398 | ||
|
|
6392929298 | ||
|
|
0f7fb9b180 | ||
|
|
4b24da8409 | ||
|
|
afc32da0c3 | ||
|
|
6aaa169a86 | ||
|
|
091a97076e | ||
|
|
d79733cafc | ||
|
|
99793f5c8a | ||
|
|
8d3cd980cf | ||
|
|
3e40ad34ab | ||
|
|
356bc09c09 | ||
|
|
0745a213b5 | ||
|
|
6c4a57dca9 | ||
|
|
c10241bf16 | ||
|
|
33e4a133cd | ||
|
|
bc2845b7aa | ||
|
|
810fcd1fc7 | ||
|
|
34f0b4eef8 | ||
|
|
3851fa5f67 | ||
|
|
2b92257523 | ||
|
|
d64ab46643 | ||
|
|
ec3b987278 | ||
|
|
b7b72651e1 | ||
|
|
322c285f68 | ||
|
|
0aef963347 | ||
|
|
b2762c32a6 | ||
|
|
2d7c37058a | ||
|
|
c440b96115 | ||
|
|
590107698f |
No files matched your search
@@ -0,0 +1,2 @@
|
||||
patreon: andre_601
|
||||
ko_fi: andre_601
|
||||
@@ -0,0 +1,62 @@
|
||||
name: Bug Report
|
||||
description: Report an issue with the plugin
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |-
|
||||
## Before opening
|
||||
Please make sure you've checked the following things first:
|
||||
|
||||
- You're using the latest release of AdvancedServerList [[Download from Modrinth](https://modrinth.com/plugin/advancedserverlist)]
|
||||
- You're using a supported Proxy/Server version. As of right now is only 1.19.x supported.
|
||||
- The issue happens with just AdvancedServerList installed.
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Platform
|
||||
description: On what platform do you use the plugin?
|
||||
options:
|
||||
- BungeeCord
|
||||
- Other (Please specify)
|
||||
- Paper
|
||||
- Purpur
|
||||
- Spigot
|
||||
- Velocity
|
||||
- Waterfall
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Other platform
|
||||
description: |-
|
||||
Please provide the name of the platform (Proxy/Server) you use, if you selected `Other (Please specify)` in the above section.
|
||||
Leave empty otherwise.
|
||||
placeholder: SomeProxy
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: |-
|
||||
Give a detailed description of what exactly happened.
|
||||
You can provide screenshots to further explain the issues.
|
||||
When sharing errors, make sure to use a site such as https://paste.helpch.at to do so.
|
||||
placeholder: When I do ... does ... happen.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Provide a detailed step-by-step explanation on how to reproduce this issue.
|
||||
placeholder: |-
|
||||
1. Do this
|
||||
2. ...
|
||||
3. Profit!
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Server List Profiles
|
||||
description: |-
|
||||
**Optional**
|
||||
Provide any Server List Profiles you use, if you believe those to be the cause of the issue.
|
||||
This text field will automatically render the text as YAML code.
|
||||
render: yaml
|
||||
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Discord Server
|
||||
about: Ask questions about the plugin in the `#advancedserverlist` channel.
|
||||
url: https://discord.gg/6dazXp6
|
||||
- name: Wiki
|
||||
about: Check the Wiki for explanations about the features and examples.
|
||||
url: https://github.com/Andre601/AdvancedServerList/wiki
|
||||
@@ -0,0 +1,34 @@
|
||||
name: Feature Request
|
||||
description: Suggest a new feature for the plugin
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |-
|
||||
## Before opening
|
||||
Please make sure you've checked the following things first:
|
||||
|
||||
- You're using the latest release of AdvancedServerList [[Download from Modrinth](https://modrinth.com/plugin/advancedserverlist)]
|
||||
- You're using a supported Proxy/Server version. As of right now is only 1.19.x supported.
|
||||
- The Feature you suggest hasn't been suggested before.
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Platforms
|
||||
description: What platforms should this feature be usable on
|
||||
multiple: true
|
||||
options:
|
||||
- Proxy (BungeeCord, Waterfall, ...)
|
||||
- Proxy (Velocity)
|
||||
- Server (Spigot, Paper, ...)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Feature
|
||||
description: |-
|
||||
Give a detailed description of what exactly should be added and/or changed in AdvancedServerList.
|
||||
You can provide screenshots to further explain the idea.
|
||||
When sharing code snippets, make sure to use a site such as https://paste.helpch.at to do so.
|
||||
placeholder: AdvancedServerList should get ... because ...
|
||||
validations:
|
||||
required: true
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 156 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
@@ -0,0 +1,50 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: maven
|
||||
directory: "/bungeecord"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- 'Type: Update Dependency'
|
||||
- 'Target: BungeeCord'
|
||||
- package-ecosystem: maven
|
||||
directory: "/core"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- 'Type: Update Dependency'
|
||||
- 'Target: Core'
|
||||
- package-ecosystem: maven
|
||||
directory: "/paper"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- 'Type: Update Dependency'
|
||||
- 'Target: PaperMC'
|
||||
- package-ecosystem: maven
|
||||
directory: "/spigot"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- 'Type: Update Dependency'
|
||||
- 'Target: Spigot'
|
||||
- package-ecosystem: maven
|
||||
directory: "/velocity"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- 'Type: Update Dependency'
|
||||
- 'Target: Velocity'
|
||||
- package-ecosystem: github-actions
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- 'Type: Update Dependency'
|
||||
- 'Target: GitHub Action'
|
||||
@@ -0,0 +1,103 @@
|
||||
#
|
||||
# Big thank you to @Kir-Antipov for providing this workflow file.
|
||||
# Check out his mc-publish action here: https://github.com/Kir-Antipov/mc-publish
|
||||
#
|
||||
|
||||
name: Publish Assets
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
buildJars:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up JDK 1.16
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '16'
|
||||
cache: 'maven'
|
||||
- name: Build Jar files
|
||||
run: mvn clean install
|
||||
- name: Save BungeeCord Jar file
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: asl-bungeecord
|
||||
path: bungeecord/target/AdvancedServerList-*.jar
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
- name: Save Paper Jar file
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: asl-paper
|
||||
path: paper/target/AdvancedServerList-*.jar
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
- name: Save Spigot Jar file
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: asl-spigot
|
||||
path: spigot/target/AdvancedServerList-*.jar
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
- name: Save Velocity Jar file
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: asl-velocity
|
||||
path: velocity/target/AdvancedServerList-*.jar
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
publish:
|
||||
needs: [buildJars]
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- platforms: BungeeCord, Waterfall
|
||||
directory: bungeecord
|
||||
loaders: |
|
||||
bungeecord
|
||||
waterfall
|
||||
- platforms: Paper
|
||||
directory: paper
|
||||
loaders: paper
|
||||
- platforms: Spigot
|
||||
directory: spigot
|
||||
loaders: spigot
|
||||
- platforms: Velocity
|
||||
directory: velocity
|
||||
loaders: velocity
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Get Jar files
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: asl-${{ matrix.directory }}
|
||||
path: ${{ matrix.directory }}/target
|
||||
- name: Get Version
|
||||
id: github-release
|
||||
run: |
|
||||
version=$(echo ${{ github.event.release.tag_name }} | cut -d'v' -f2)
|
||||
echo "::set-output name=version::$version"
|
||||
- name: Upload AdvancedServerList (${{ matrix.loaders }}) to GitHub and Modrinth
|
||||
uses: Kir-Antipov/mc-publish@v3.2
|
||||
with:
|
||||
name: ${{ github.event.release.tag_name }} (${{ matrix.platforms }})
|
||||
version: ${{ steps.github-release.outputs.version }}
|
||||
version-type: release
|
||||
files: ${{ matrix.directory}}/target/AdvancedServerList-*.jar
|
||||
files-secondary: ""
|
||||
loaders: ${{ matrix.loaders }}
|
||||
version-resolver: releases
|
||||
game-versions: |
|
||||
1.19
|
||||
1.19.1
|
||||
1.19.2
|
||||
java: 16
|
||||
modrinth-id: xss83sOY
|
||||
modrinth-featured: false
|
||||
modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Andre_601
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,84 @@
|
||||
# AdvancedServerList
|
||||
![platform] ![tested]
|
||||
|
||||
AdvancedServerList is a plugin made for SpigotMC, PaperMC, BungeeCord/Waterfall and Velocity. It allows you to create server list profiles to display based on priority and conditions.
|
||||
|
||||
## What is a Server List Profile?
|
||||
A Server List Profile refers to a YAML file located in the plugin's `profiles` directory.
|
||||
It allows you to configure specific aspects of the server display in the MC-Client's multiplayer server list, such as the MOTD, player count text, player count hover or Favicon.
|
||||
|
||||
> [*Read More*][profiles]
|
||||
|
||||
### Conditions
|
||||
Thanks to conditions can you determine when a profile should be displayed in the player’s server list, to allow displaying specific text (i.e. a warning when they are using an outdated version).
|
||||
|
||||
When multiple profiles exist that have valid conditions will the one with the highest priority (Higher number = higher priority) be selected. Having no conditions makes the profile automatically return true.
|
||||
|
||||
> [*Read More*][conditions]
|
||||
|
||||
### Placeholders
|
||||
Placeholders can be used within conditions to further customize them. They can also be used in any other text option (motd, playerCount and players) to display their respective values.
|
||||
The format is `${<target> <identifier>}` which was adopted from BungeeTabListPlus. Depending on what platform you use the plugin on are only specific placeholders available.
|
||||
|
||||
When using the SpigotMC/PaperMC version can you also use placeholders from [PlaceholderAPI][placeholderapi] using its `%<identifier>_<values>%` placeholder format. PlaceholderAPI needs to be installed for that.
|
||||
|
||||
> [*Read More*][placeholders]
|
||||
|
||||
### Formatting
|
||||
The plugin uses the MiniMessage format for a consistent, easy way of formatting your text.
|
||||
Only certain options are usable for each option. As an example does motd support HEX colours and gradients, while the other options only support default colour codes.
|
||||
|
||||
> [*Read More*][minimessage]
|
||||
|
||||
## Downloads
|
||||
|
||||
<a href="https://modrinth.com/plugin/advancedserverlist" target="_blank">
|
||||
<img src="https://raw.githubusercontent.com/intergrav/devins-badges/main/badges/modrinth_vector.svg" height="64" />
|
||||
</a>
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Dependency | Platforms | Required? |
|
||||
| ---------------- | ------------- | --------- |
|
||||
| [ProtocolLib] | Spigot | Yes |
|
||||
| [PlaceholderAPI] | Spigot, Paper | No |
|
||||
|
||||
## Statistics
|
||||
|
||||
This plugin sends statistics to [bStats] to display.
|
||||
You can disable this in the global bStats config file located in `/plugins/bstats/`
|
||||
|
||||
- [BungeeCord][bstats-bungee]
|
||||
- [Paper/Spigot][bstats-spigot]
|
||||
- [Velocity][bstats-velocity]
|
||||
|
||||
## Screenshots
|
||||
|
||||
<a href="https://modrinth.com/plugin/advancedserverlist/gallery" target="_blank">
|
||||
<img src="https://raw.githubusercontent.com/intergrav/devins-badges/main/badges/modrinth-gallery_vector.svg" height="64" />
|
||||
</a>
|
||||
|
||||
<!-- Links -->
|
||||
[profiles]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles
|
||||
[conditions]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#conditions
|
||||
[placeholders]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#placeholders
|
||||
[minimessage]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#minimessage
|
||||
|
||||
[placeholderapi]: https://www.spigotmc.org/resources/6245/
|
||||
|
||||
[modrinth]: https://modrinth.com/plugin/advancedserverlist
|
||||
|
||||
[protocollib]: https://www.spigotmc.org/resources/1997/
|
||||
[placeholderapi]: https://www.spigotmc.org/resources/6245/
|
||||
|
||||
[bstats]: https://bstats.org
|
||||
[bstats-bungee]: https://bstats.org/plugin/bungeecord/AdvancedServerList/15585
|
||||
[bstats-spigot]: https://bstats.org/plugin/bukkit/AdvancedServerList/15584
|
||||
[bstats-velocity]: https://bstats.org/plugin/velocity/AdvancedServerList/15587
|
||||
|
||||
[gallery]: https://modrinth.com/mod/advancedserverlist/gallery
|
||||
|
||||
<!-- Badges -->
|
||||
[platform]: https://img.shields.io/badge/Platforms-Spigot%20%7C%20Paper%20%7C%20BungeeCord%20%7C%20Velocity-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSJ3aGl0ZSI+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTEuMDYzIDEuNDU2YTEuNzUgMS43NSAwIDAxMS44NzQgMGw4LjM4MyA1LjMxNmExLjc1IDEuNzUgMCAwMTAgMi45NTZsLTguMzgzIDUuMzE2YTEuNzUgMS43NSAwIDAxLTEuODc0IDBMMi42OCA5LjcyOGExLjc1IDEuNzUgMCAwMTAtMi45NTZsOC4zODMtNS4zMTZ6bTEuMDcxIDEuMjY3YS4yNS4yNSAwIDAwLS4yNjggMEwzLjQ4MyA4LjAzOWEuMjUuMjUgMCAwMDAgLjQyMmw4LjM4MyA1LjMxNmEuMjUuMjUgMCAwMC4yNjggMGw4LjM4My01LjMxNmEuMjUuMjUgMCAwMDAtLjQyMmwtOC4zODMtNS4zMTZ6Ij48L3BhdGg+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMS44NjcgMTIuMzI0YS43NS43NSAwIDAxMS4wMzUtLjIzMmw4Ljk2NCA1LjY4NWEuMjUuMjUgMCAwMC4yNjggMGw4Ljk2NC01LjY4NWEuNzUuNzUgMCAwMS44MDQgMS4yNjdsLTguOTY1IDUuNjg1YTEuNzUgMS43NSAwIDAxLTEuODc0IDBsLTguOTY1LTUuNjg1YS43NS43NSAwIDAxLS4yMzEtMS4wMzV6Ij48L3BhdGg+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMS44NjcgMTYuMzI0YS43NS43NSAwIDAxMS4wMzUtLjIzMmw4Ljk2NCA1LjY4NWEuMjUuMjUgMCAwMC4yNjggMGw4Ljk2NC01LjY4NWEuNzUuNzUgMCAwMS44MDQgMS4yNjdsLTguOTY1IDUuNjg1YTEuNzUgMS43NSAwIDAxLTEuODc0IDBsLTguOTY1LTUuNjg1YS43NS43NSAwIDAxLS4yMzEtMS4wMzV6Ij48L3BhdGg+PC9zdmc+
|
||||
|
||||
[tested]: https://img.shields.io/badge/Tested%20Versions-1.19%20%7C%201.19.1%20%7C%201.19.2-blue?style=for-the-badge&logo=image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSJ3aGl0ZSI+PHBhdGggZD0iTTE3LjI4IDkuMjhhLjc1Ljc1IDAgMDAtMS4wNi0xLjA2bC01Ljk3IDUuOTctMi40Ny0yLjQ3YS43NS43NSAwIDAwLTEuMDYgMS4wNmwzIDNhLjc1Ljc1IDAgMDAxLjA2IDBsNi41LTYuNXoiPjwvcGF0aD48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0zLjc1IDJBMS43NSAxLjc1IDAgMDAyIDMuNzV2MTYuNWMwIC45NjYuNzg0IDEuNzUgMS43NSAxLjc1aDE2LjVBMS43NSAxLjc1IDAgMDAyMiAyMC4yNVYzLjc1QTEuNzUgMS43NSAwIDAwMjAuMjUgMkgzLjc1ek0zLjUgMy43NWEuMjUuMjUgMCAwMS4yNS0uMjVoMTYuNWEuMjUuMjUgMCAwMS4yNS4yNXYxNi41YS4yNS4yNSAwIDAxLS4yNS4yNUgzLjc1YS4yNS4yNSAwIDAxLS4yNS0uMjVWMy43NXoiPjwvcGF0aD48L3N2Zz4=
|
||||
+48
-8
@@ -1,4 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ MIT License
|
||||
~
|
||||
~ Copyright (c) 2022 Andre_601
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in all
|
||||
~ copies or substantial portions of the Software.
|
||||
~
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
~ SOFTWARE.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
@@ -36,21 +61,28 @@
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.17-R0.1-SNAPSHOT</version>
|
||||
<version>1.19-R0.1-SNAPSHOT</version>
|
||||
<type>jar</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.17-R0.1-SNAPSHOT</version>
|
||||
<version>1.19-R0.1-SNAPSHOT</version>
|
||||
<type>javadoc</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-platform-bungeecord</artifactId>
|
||||
<version>4.1.0</version>
|
||||
<version>4.1.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bungeecord</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -71,17 +103,25 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<version>3.4.0</version>
|
||||
<configuration>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.spongepowered.configurate</pattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.velocity.depends.configurate</shadedPattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.bungeecord.depends.configurate</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>net.kyori.adventure</pattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.bungeecord.depends.adventure</shadedPattern>
|
||||
<pattern>net.kyori</pattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.bungeecord.depends.kyori</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.bstats</pattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.bungeecord.depends.bstats</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.github.benmanes.caffeine</pattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.bungeecord.depends.caffeine</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<filters>
|
||||
|
||||
+86
-8
@@ -1,25 +1,67 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.bungeecord;
|
||||
|
||||
import ch.andre601.advancedserverlist.bungeecord.commands.CmdAdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.bungeecord.events.JoinEvent;
|
||||
import ch.andre601.advancedserverlist.bungeecord.events.PingEvent;
|
||||
import ch.andre601.advancedserverlist.bungeecord.logging.BungeeLogger;
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.ProxyLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.ProxyCore;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
import net.md_5.bungee.api.Favicon;
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import org.bstats.bungeecord.Metrics;
|
||||
import org.bstats.charts.SimplePie;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BungeeCordCore extends Plugin implements PluginCore{
|
||||
public class BungeeCordCore extends Plugin implements ProxyCore<Favicon, ServerPing.PlayerInfo>{
|
||||
|
||||
private AdvancedServerList core;
|
||||
private final ProxyLogger logger = new BungeeLogger(getLogger());
|
||||
private FaviconHandler<Favicon> faviconHandler = null;
|
||||
private final PluginLogger logger = new BungeeLogger(getLogger());
|
||||
|
||||
@Override
|
||||
public void onEnable(){
|
||||
this.core = new AdvancedServerList(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable(){
|
||||
core.disable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCommands(){
|
||||
getProxy().getPluginManager().registerCommand(this, new CmdAdvancedServerList(this));
|
||||
@@ -27,36 +69,72 @@ public class BungeeCordCore extends Plugin implements PluginCore{
|
||||
|
||||
@Override
|
||||
public void loadEvents(){
|
||||
new JoinEvent(this);
|
||||
new PingEvent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMetrics(){
|
||||
new Metrics(this, 15585).addCustomChart(new SimplePie("profiles",
|
||||
() -> String.valueOf(core.getFileHandler().getProfiles().size())
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearFaviconCache(){
|
||||
if(faviconHandler == null)
|
||||
return;
|
||||
|
||||
faviconHandler.clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdvancedServerList getCore(){
|
||||
return core;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getPath(){
|
||||
public Path getFolderPath(){
|
||||
return getDataFolder().toPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProxyLogger getProxyLogger(){
|
||||
public PluginLogger getPluginLogger(){
|
||||
return logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProxyName(){
|
||||
public FaviconHandler<Favicon> getFaviconHandler(){
|
||||
if(faviconHandler == null)
|
||||
faviconHandler = new FaviconHandler<>(core);
|
||||
|
||||
return faviconHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlatformName(){
|
||||
return getProxy().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProxyVersion(){
|
||||
public String getPlatformVersion(){
|
||||
return getProxy().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServerPing.PlayerInfo> createPlayers(List<String> lines, Placeholders... placeholders){
|
||||
List<ServerPing.PlayerInfo> players = new ArrayList<>(lines.size());
|
||||
|
||||
for(String line : lines){
|
||||
String parsed = ComponentParser.text(line)
|
||||
.replacements(placeholders[0])
|
||||
.replacements(placeholders[1])
|
||||
.toString();
|
||||
|
||||
players.add(new ServerPing.PlayerInfo(parsed, UUID.randomUUID()));
|
||||
}
|
||||
|
||||
return players;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.bungeecord;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public class BungeePlayer extends GenericPlayer<ProxiedPlayer>{
|
||||
|
||||
public BungeePlayer(String name, int protocol){
|
||||
this.name = name;
|
||||
this.protocol = protocol;
|
||||
}
|
||||
}
|
||||
+26
-1
@@ -1,3 +1,28 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.bungeecord.commands;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.CmdSender;
|
||||
@@ -22,6 +47,6 @@ public class BungeeCmdSender implements CmdSender{
|
||||
|
||||
@Override
|
||||
public void sendMsg(String msg, Object... args){
|
||||
bungeeAudiences.sender(sender).sendMessage(ComponentParser.toComponent(String.format(msg, args)));
|
||||
bungeeAudiences.sender(sender).sendMessage(ComponentParser.text(String.format(msg, args)).toComponent());
|
||||
}
|
||||
}
|
||||
+25
@@ -1,3 +1,28 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.bungeecord.commands;
|
||||
|
||||
import ch.andre601.advancedserverlist.bungeecord.BungeeCordCore;
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.bungeecord.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.bungeecord.BungeeCordCore;
|
||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public class JoinEvent implements Listener{
|
||||
|
||||
private final BungeeCordCore plugin;
|
||||
|
||||
public JoinEvent(BungeeCordCore plugin){
|
||||
this.plugin = plugin;
|
||||
plugin.getProxy().getPluginManager().registerListener(plugin, this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PostLoginEvent event){
|
||||
InetSocketAddress address = (InetSocketAddress)event.getPlayer().getPendingConnection().getSocketAddress();
|
||||
plugin.getCore().getPlayerHandler().addPlayer(event.getPlayer().getName(), address.getHostString());
|
||||
}
|
||||
}
|
||||
+96
-15
@@ -1,10 +1,40 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.bungeecord.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.bungeecord.BungeeCordCore;
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.bungeecord.BungeePlayer;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ProfileManager;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
|
||||
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
|
||||
import net.md_5.bungee.api.Favicon;
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.event.ProxyPingEvent;
|
||||
@@ -12,7 +42,7 @@ import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
import net.md_5.bungee.event.EventPriority;
|
||||
|
||||
import java.util.List;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public class PingEvent implements Listener{
|
||||
|
||||
@@ -30,33 +60,84 @@ public class PingEvent implements Listener{
|
||||
if(protocol == null)
|
||||
return;
|
||||
|
||||
ServerListProfile profile = plugin.getCore().getServerListProfile(protocol.getProtocol());
|
||||
if(!profile.getMotd().isEmpty()){
|
||||
List<String> motd = profile.getMotd();
|
||||
if(motd.size() > 2)
|
||||
motd = motd.subList(0, 2);
|
||||
String playerName = plugin.getCore().getPlayerHandler().getPlayerByIp(
|
||||
((InetSocketAddress)event.getConnection().getSocketAddress()).getHostString()
|
||||
);
|
||||
InetSocketAddress host = event.getConnection().getVirtualHost();
|
||||
|
||||
int online = ping.getPlayers().getOnline();
|
||||
int max = ping.getPlayers().getMax();
|
||||
|
||||
PlayerPlaceholders playerPlaceholders = new PlayerPlaceholders(new BungeePlayer(playerName, protocol.getProtocol()));
|
||||
ServerPlaceholders serverPlaceholders = new ServerPlaceholders(online, max, host == null ? null : host.getHostString());
|
||||
|
||||
ServerListProfile profile = ProfileManager.get(plugin.getCore())
|
||||
.replacements(playerPlaceholders)
|
||||
.replacements(serverPlaceholders)
|
||||
.getProfile();
|
||||
|
||||
if(profile == null)
|
||||
return;
|
||||
|
||||
if(profile.isExtraPlayersEnabled()){
|
||||
max = online + profile.getExtraPlayers();
|
||||
ping.getPlayers().setMax(max);
|
||||
}
|
||||
|
||||
serverPlaceholders = new ServerPlaceholders(online, max, host == null ? null : host.getHostString());
|
||||
|
||||
if(!profile.getMotd().isEmpty()){
|
||||
TextComponent component = new TextComponent(BungeeComponentSerializer.get().serialize(
|
||||
ComponentParser.toComponent(motd)
|
||||
ComponentParser.list(profile.getMotd())
|
||||
.replacements(playerPlaceholders)
|
||||
.replacements(serverPlaceholders)
|
||||
.toComponent()
|
||||
));
|
||||
|
||||
ping.setDescriptionComponent(component);
|
||||
}
|
||||
|
||||
if(!profile.getPlayerCount().isEmpty()){
|
||||
protocol.setName(ComponentParser.toString(profile.getPlayerCount()));
|
||||
if(profile.shouldHidePlayers()){
|
||||
ping.setPlayers(null);
|
||||
}
|
||||
|
||||
if(!profile.getPlayerCount().isEmpty() && !profile.shouldHidePlayers()){
|
||||
protocol.setName(ComponentParser.text(profile.getPlayerCount())
|
||||
.replacements(playerPlaceholders)
|
||||
.replacements(serverPlaceholders)
|
||||
.toString()
|
||||
);
|
||||
protocol.setProtocol(-1);
|
||||
}
|
||||
|
||||
if(!profile.getPlayers().isEmpty()){
|
||||
ServerPing.PlayerInfo[] players = AdvancedServerList.getPlayers(ServerPing.PlayerInfo.class, profile.getPlayers())
|
||||
if(!profile.getPlayers().isEmpty() && !profile.shouldHidePlayers()){
|
||||
ServerPing.PlayerInfo[] playerInfos = plugin.createPlayers(profile.getPlayers(), playerPlaceholders, serverPlaceholders)
|
||||
.toArray(new ServerPing.PlayerInfo[0]);
|
||||
if(players.length > 0)
|
||||
ping.getPlayers().setSample(players);
|
||||
|
||||
if(playerInfos.length > 0)
|
||||
ping.getPlayers().setSample(playerInfos);
|
||||
}
|
||||
|
||||
if(!profile.getFavicon().isEmpty()){
|
||||
String favName = StringReplacer.replace(profile.getFavicon(), playerPlaceholders.getReplacements());
|
||||
|
||||
Favicon favicon = plugin.getFaviconHandler().getFavicon(favName, image -> {
|
||||
try{
|
||||
return Favicon.create(image);
|
||||
}catch(Exception ex){
|
||||
plugin.getPluginLogger().warn("Unable to create Favicon. %s", ex.getMessage());
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
if(favicon == null){
|
||||
plugin.getPluginLogger().warn("Could not obtain valid Favicon to use.");
|
||||
ping.setFavicon(ping.getFaviconObject());
|
||||
}else{
|
||||
ping.setFavicon(favicon);
|
||||
}
|
||||
}
|
||||
|
||||
ping.setFavicon(ping.getFaviconObject());
|
||||
ping.setVersion(protocol);
|
||||
|
||||
event.setResponse(ping);
|
||||
|
||||
+31
-6
@@ -1,11 +1,36 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.bungeecord.logging;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.ProxyLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class BungeeLogger implements ProxyLogger{
|
||||
public class BungeeLogger implements PluginLogger{
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
@@ -14,13 +39,13 @@ public class BungeeLogger implements ProxyLogger{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String msg){
|
||||
logger.info(msg);
|
||||
public void info(String msg, Object... args){
|
||||
logger.info(String.format(msg, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg){
|
||||
logger.warning(msg);
|
||||
public void warn(String msg, Object... args){
|
||||
logger.warning(String.format(msg, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+39
-2
@@ -1,4 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ MIT License
|
||||
~
|
||||
~ Copyright (c) 2022 Andre_601
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in all
|
||||
~ copies or substantial portions of the Software.
|
||||
~
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
~ SOFTWARE.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
@@ -39,10 +64,22 @@
|
||||
<artifactId>adventure-text-serializer-legacy</artifactId>
|
||||
<version>4.11.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||
<artifactId>caffeine</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>AdvancedServerList-Core-${plugin.version}</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${project.basedir}/src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@@ -52,9 +89,9 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<version>3.4.0</version>
|
||||
<configuration>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
|
||||
@@ -1,57 +1,60 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.commands.CommandHandler;
|
||||
import ch.andre601.advancedserverlist.core.file.FileHandler;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.ProxyLogger;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ConditionHolder;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.PlayerHandler;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
public class AdvancedServerList{
|
||||
|
||||
private final PluginCore plugin;
|
||||
private final PluginCore<?> plugin;
|
||||
private final FileHandler fileHandler;
|
||||
private final CommandHandler commandHandler;
|
||||
private final PlayerHandler playerHandler;
|
||||
|
||||
public AdvancedServerList(PluginCore plugin){
|
||||
private String version;
|
||||
|
||||
public AdvancedServerList(PluginCore<?> plugin){
|
||||
this.plugin = plugin;
|
||||
this.fileHandler = new FileHandler(this);
|
||||
this.commandHandler = new CommandHandler(this);
|
||||
this.playerHandler = new PlayerHandler(this);
|
||||
|
||||
load();
|
||||
}
|
||||
|
||||
public static <T> List<T> getPlayers(Class<T> clazz, List<String> lines){
|
||||
try{
|
||||
final List<T> players = new ArrayList<>(lines.size());
|
||||
final Constructor<T> constructor = clazz.getDeclaredConstructor(String.class, UUID.class);
|
||||
|
||||
constructor.setAccessible(true);
|
||||
|
||||
for(String line : lines){
|
||||
players.add(constructor.newInstance(
|
||||
ComponentParser.toString(line), UUID.randomUUID()
|
||||
));
|
||||
}
|
||||
|
||||
return players;
|
||||
}catch(NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException ex){
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
public ProxyLogger getProxyLogger(){
|
||||
return plugin.getProxyLogger();
|
||||
}
|
||||
|
||||
public Path getPath(){
|
||||
return plugin.getPath();
|
||||
public PluginCore<?> getPlugin(){
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public FileHandler getFileHandler(){
|
||||
@@ -62,51 +65,88 @@ public class AdvancedServerList{
|
||||
return commandHandler;
|
||||
}
|
||||
|
||||
public ServerListProfile getServerListProfile(int protocol){
|
||||
for(ServerListProfile profile : getFileHandler().getProfiles()){
|
||||
if(profile.getMotd().isEmpty() && profile.getPlayers().isEmpty() && profile.getPlayerCount().isEmpty())
|
||||
continue;
|
||||
public PlayerHandler getPlayerHandler(){
|
||||
return playerHandler;
|
||||
}
|
||||
|
||||
ConditionHolder conditions = profile.getConditions();
|
||||
if(conditions.eval(protocol, getProxyLogger()))
|
||||
return profile;
|
||||
}
|
||||
|
||||
return null;
|
||||
public String getVersion(){
|
||||
return version;
|
||||
}
|
||||
|
||||
public void disable(){
|
||||
getPlugin().getPluginLogger().info("Saving cache.data file...");
|
||||
getPlayerHandler().save();
|
||||
getPlugin().getPluginLogger().info("AdvancedServerList disabled!");
|
||||
}
|
||||
|
||||
public void clearFaviconCache(){
|
||||
plugin.clearFaviconCache();
|
||||
}
|
||||
|
||||
private void load(){
|
||||
printBanner();
|
||||
getProxyLogger().info("Starting AdvancedServerList...");
|
||||
resolveVersion();
|
||||
|
||||
getPlugin().getPluginLogger().info("Starting AdvancedServerList v%s...", version);
|
||||
|
||||
getPlugin().getPluginLogger().info("Platform: " + plugin.getPlatformName() + " " + plugin.getPlatformVersion());
|
||||
|
||||
getProxyLogger().info("Proxy: " + plugin.getProxyName() + " " + plugin.getProxyVersion());
|
||||
|
||||
if(getFileHandler().loadProfiles()){
|
||||
getProxyLogger().info("Successfully loaded " + getFileHandler().getProfiles().size() + " profiles!");
|
||||
if(getFileHandler().loadConfig()){
|
||||
getPlugin().getPluginLogger().info("Successfully loaded config.yml!");
|
||||
}else{
|
||||
getProxyLogger().warn("Unable to load profiles! Check previous lines for errors.");
|
||||
getPlugin().getPluginLogger().warn("Unable to load config.yml! Check previous lines for errors.");
|
||||
return;
|
||||
}
|
||||
|
||||
getProxyLogger().info("Loading Commands...");
|
||||
if(getFileHandler().loadProfiles()){
|
||||
getPlugin().getPluginLogger().info("Successfully loaded " + getFileHandler().getProfiles().size() + " profiles!");
|
||||
}else{
|
||||
getPlugin().getPluginLogger().warn("Unable to load profiles! Check previous lines for errors.");
|
||||
return;
|
||||
}
|
||||
|
||||
Path folder = getPlugin().getFolderPath().resolve("favicons");
|
||||
if(!folder.toFile().exists() && folder.toFile().mkdirs())
|
||||
getPlugin().getPluginLogger().info("Successfully created favicons folder.");
|
||||
|
||||
getPlugin().getPluginLogger().info("Loading Commands...");
|
||||
plugin.loadCommands();
|
||||
getProxyLogger().info("Commands loaded!");
|
||||
|
||||
getProxyLogger().info("Loading events...");
|
||||
getPlugin().getPluginLogger().info("Commands loaded!");
|
||||
|
||||
getPlugin().getPluginLogger().info("Loading events...");
|
||||
plugin.loadEvents();
|
||||
getProxyLogger().info("Events loaded!");
|
||||
|
||||
getProxyLogger().info("AdvancedServerList is ready!");
|
||||
getPlugin().getPluginLogger().info("Events loaded!");
|
||||
|
||||
getPlugin().getPluginLogger().info("Loading cache.data...");
|
||||
getPlayerHandler().load();
|
||||
|
||||
getPlugin().getPluginLogger().info("Loading bStats metrics. Disable it in the global config under /plugins/bstats/");
|
||||
plugin.loadMetrics();
|
||||
getPlugin().getPluginLogger().info("Metrics loaded!");
|
||||
|
||||
getPlugin().getPluginLogger().info("AdvancedServerList is ready!");
|
||||
}
|
||||
|
||||
private void printBanner(){
|
||||
getProxyLogger().info("");
|
||||
getProxyLogger().info(" _____ _");
|
||||
getProxyLogger().info(" /\\ / ____| |");
|
||||
getProxyLogger().info(" / \\ | (___ | |");
|
||||
getProxyLogger().info(" / /\\ \\ \\___ \\| |");
|
||||
getProxyLogger().info(" / ____ \\ ____) | |____");
|
||||
getProxyLogger().info("/_/ \\_\\_____/|______|");
|
||||
getProxyLogger().info("");
|
||||
getPlugin().getPluginLogger().info("");
|
||||
getPlugin().getPluginLogger().info(" _____ _");
|
||||
getPlugin().getPluginLogger().info(" /\\ / ____| |");
|
||||
getPlugin().getPluginLogger().info(" / \\ | (___ | |");
|
||||
getPlugin().getPluginLogger().info(" / /\\ \\ \\___ \\| |");
|
||||
getPlugin().getPluginLogger().info(" / ____ \\ ____) | |____");
|
||||
getPlugin().getPluginLogger().info("/_/ \\_\\_____/|______|");
|
||||
getPlugin().getPluginLogger().info("");
|
||||
}
|
||||
|
||||
private void resolveVersion(){
|
||||
try(InputStream is = getClass().getResourceAsStream("/version.properties")){
|
||||
Properties properties = new Properties();
|
||||
|
||||
properties.load(is);
|
||||
|
||||
version = properties.getProperty("version");
|
||||
}catch(IOException ex){
|
||||
version = "UNKNOWN";
|
||||
}
|
||||
}
|
||||
}
|
||||
+50
-10
@@ -1,3 +1,28 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.commands;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
@@ -12,30 +37,45 @@ public class CommandHandler{
|
||||
}
|
||||
|
||||
public void handle(CmdSender sender, String[] args){
|
||||
String errorPrefix = "<grey>[<gradient:dark_red:red>AdvancedServerList</gradient>]";
|
||||
String prefix = "<grey>[<gradient:aqua:white>AdvancedServerList</gradient>]";
|
||||
|
||||
if(args.length == 0 || args[0].equalsIgnoreCase("help")){
|
||||
if(sender.hasPermission("advancedserverlist.command.help")){
|
||||
sender.sendMsg("AdvancedServerList Commands");
|
||||
sender.sendMsg("%s - Commands", prefix);
|
||||
sender.sendMsg();
|
||||
sender.sendMsg("<aqua>/asl help <grey>- Shows this help.");
|
||||
sender.sendMsg("<gradient:aqua:white>/asl help</gradient> <grey>- Shows this Help");
|
||||
sender.sendMsg();
|
||||
sender.sendMsg("<aqua>/asl reload <grey>- Reloads the profiles.");
|
||||
sender.sendMsg("<gradient:aqua:white>/asl reload</gradient> <grey>- Reloads the plugin");
|
||||
}else{
|
||||
sender.sendMsg("<red>You do not have the permissions to execute this command!");
|
||||
sender.sendMsg("%s <red>You do not have permissions to execute this command!", errorPrefix);
|
||||
}
|
||||
}else
|
||||
if(args[0].equalsIgnoreCase("reload")){
|
||||
if(sender.hasPermission("advancedserverlist.command.reload")){
|
||||
sender.sendMsg("<grey>Reloading Profiles...");
|
||||
if(core.getFileHandler().reloadProfiles()){
|
||||
sender.sendMsg("<green>Successfully loaded %d Profiles!", core.getFileHandler().getProfiles().size());
|
||||
sender.sendMsg("%s Reloading plugin...", prefix);
|
||||
|
||||
if(core.getFileHandler().reloadConfig()){
|
||||
sender.sendMsg("%s <green>Reloaded <grey>config.yml</grey>!", prefix);
|
||||
}else{
|
||||
sender.sendMsg("<red>Error while reloading Profiles. No profiles have been loaded.");
|
||||
sender.sendMsg("%s <red>Error while reloading the <grey>config.yml</grey>!", errorPrefix);
|
||||
}
|
||||
|
||||
sender.sendMsg("<green>Reload complete!");
|
||||
if(core.getFileHandler().reloadProfiles()){
|
||||
sender.sendMsg("%s <green>Loaded <grey>%d Profile(s)</grey>!", prefix, core.getFileHandler().getProfiles().size());
|
||||
}else{
|
||||
sender.sendMsg("%s <red>Cannot load Profiles!", errorPrefix);
|
||||
}
|
||||
|
||||
core.clearFaviconCache();
|
||||
sender.sendMsg("%s <green>Successfully cleared Favicon cache!", prefix);
|
||||
|
||||
sender.sendMsg("%s <green>Reload complete!", prefix);
|
||||
}else{
|
||||
sender.sendMsg("%s <red>You do not have permissions to execute this command!", errorPrefix);
|
||||
}
|
||||
}else{
|
||||
sender.sendMsg("<red>Unknown subcommand <grey>%s</grey>. Use <grey>/asl help</grey> for a list of commands.", args[0]);
|
||||
sender.sendMsg("%s <red>Unknown subcommand <grey>%s</grey>. Use <grey>/asl help</grey> for a list of commands.", prefix, args[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,37 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.file;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.ProxyLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
@@ -18,24 +42,53 @@ import java.util.List;
|
||||
|
||||
public class FileHandler{
|
||||
|
||||
private final FilenameFilter profileFilter = (dir, name) -> name.endsWith(".yml");
|
||||
|
||||
private final AdvancedServerList plugin;
|
||||
private final ProxyLogger logger;
|
||||
private final PluginLogger logger;
|
||||
|
||||
private final Path config;
|
||||
private final Path profilesFolder;
|
||||
|
||||
private final List<ServerListProfile> profiles = new ArrayList<>();
|
||||
|
||||
public FileHandler(AdvancedServerList plugin){
|
||||
this.plugin = plugin;
|
||||
this.logger = plugin.getProxyLogger();
|
||||
this.profilesFolder = plugin.getPath().resolve("profiles");
|
||||
private ConfigurationNode node = null;
|
||||
|
||||
public FileHandler(AdvancedServerList core){
|
||||
this.plugin = core;
|
||||
this.logger = core.getPlugin().getPluginLogger();
|
||||
|
||||
this.config = core.getPlugin().getFolderPath().resolve("config.yml");
|
||||
this.profilesFolder = core.getPlugin().getFolderPath().resolve("profiles");
|
||||
}
|
||||
|
||||
public List<ServerListProfile> getProfiles(){
|
||||
return profiles;
|
||||
}
|
||||
|
||||
public boolean loadConfig(){
|
||||
logger.info("Loading config.yml...");
|
||||
File folder = config.toFile().getParentFile();
|
||||
if(!folder.exists() && !folder.mkdirs()){
|
||||
logger.warn("Couldn't create folder for plugin. Is it missing Write permissions?");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!config.toFile().exists()){
|
||||
try(InputStream stream = plugin.getClass().getResourceAsStream("/config.yml")){
|
||||
if(stream == null){
|
||||
logger.warn("Cannot retrieve config.yml from plugin.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Files.copy(stream, config);
|
||||
}catch(IOException ex){
|
||||
logger.warn("Cannot create config.yml for plugin.", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return reloadConfig();
|
||||
}
|
||||
|
||||
public boolean loadProfiles(){
|
||||
logger.info("Loading profiles...");
|
||||
if(!profilesFolder.toFile().exists() && profilesFolder.toFile().mkdirs()){
|
||||
@@ -56,6 +109,37 @@ public class FileHandler{
|
||||
return reloadProfiles();
|
||||
}
|
||||
|
||||
public boolean reloadConfig(){
|
||||
return (node = getConfigurationNode(config)) != null;
|
||||
}
|
||||
|
||||
public boolean reloadProfiles(){
|
||||
profiles.clear();
|
||||
|
||||
File[] files = profilesFolder.toFile().listFiles(((dir, name) -> name.endsWith(".yml")));
|
||||
if(files == null || files.length == 0){
|
||||
logger.warn("Cannot load files from profiles folder! No valid YAML files present.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for(File file : files){
|
||||
ConfigurationNode tmp = getConfigurationNode(file.toPath());
|
||||
if(tmp == null)
|
||||
continue;
|
||||
|
||||
profiles.add(new ServerListProfile(tmp, logger));
|
||||
logger.info("Loaded " + file.getName());
|
||||
}
|
||||
|
||||
if(profiles.isEmpty()){
|
||||
logger.warn("Couldn't load any profile from profiles folder!");
|
||||
return false;
|
||||
}
|
||||
|
||||
profiles.sort(Comparator.comparing(ServerListProfile::getPriority).reversed());
|
||||
return !profiles.isEmpty();
|
||||
}
|
||||
|
||||
public ConfigurationNode getConfigurationNode(Path path){
|
||||
YamlConfigurationLoader loader = YamlConfigurationLoader.builder()
|
||||
.path(path)
|
||||
@@ -69,30 +153,7 @@ public class FileHandler{
|
||||
}
|
||||
}
|
||||
|
||||
public boolean reloadProfiles(){
|
||||
profiles.clear();
|
||||
|
||||
File[] files = profilesFolder.toFile().listFiles(profileFilter);
|
||||
if(files == null || files.length == 0){
|
||||
logger.warn("Cannot load files from profiles folder! No valid YAML files present.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for(File file : files){
|
||||
ConfigurationNode tmp = getConfigurationNode(file.toPath());
|
||||
if(tmp == null)
|
||||
continue;
|
||||
|
||||
profiles.add(new ServerListProfile(tmp));
|
||||
logger.info("Loaded " + file.getName());
|
||||
}
|
||||
|
||||
if(profiles.isEmpty()){
|
||||
logger.warn("Couldn't load any profile from profiles folder!");
|
||||
return false;
|
||||
}
|
||||
|
||||
profiles.sort(Comparator.comparing(ServerListProfile::getPriority).reversed());
|
||||
return !profiles.isEmpty();
|
||||
public String getString(String def, Object... path){
|
||||
return node.node(path).getString(def);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,29 @@
|
||||
package ch.andre601.advancedserverlist.core.interfaces;
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
package ch.andre601.advancedserverlist.core.interfaces;
|
||||
|
||||
public interface CmdSender{
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
package ch.andre601.advancedserverlist.core.interfaces;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.commands.CommandHandler;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public interface PluginCore{
|
||||
|
||||
void loadCommands();
|
||||
|
||||
void loadEvents();
|
||||
|
||||
void loadMetrics();
|
||||
|
||||
AdvancedServerList getCore();
|
||||
|
||||
Path getPath();
|
||||
|
||||
ProxyLogger getProxyLogger();
|
||||
|
||||
String getProxyName();
|
||||
|
||||
String getProxyVersion();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.interfaces;
|
||||
|
||||
public interface PluginLogger{
|
||||
|
||||
void info(String msg, Object... args);
|
||||
|
||||
void warn(String msg, Object... args);
|
||||
|
||||
void warn(String msg, Throwable throwable);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package ch.andre601.advancedserverlist.core.interfaces;
|
||||
|
||||
public interface ProxyLogger{
|
||||
|
||||
void info(String msg);
|
||||
|
||||
void warn(String msg);
|
||||
|
||||
void warn(String msg, Throwable throwable);
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.interfaces.core;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public interface PluginCore<F>{
|
||||
|
||||
void loadCommands();
|
||||
|
||||
void loadEvents();
|
||||
|
||||
void loadMetrics();
|
||||
|
||||
void clearFaviconCache();
|
||||
|
||||
AdvancedServerList getCore();
|
||||
|
||||
Path getFolderPath();
|
||||
|
||||
PluginLogger getPluginLogger();
|
||||
|
||||
FaviconHandler<F> getFaviconHandler();
|
||||
|
||||
String getPlatformName();
|
||||
|
||||
String getPlatformVersion();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.interfaces.core;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ProxyCore<F, P> extends PluginCore<F>{
|
||||
List<P> createPlayers(List<String> lines, Placeholders... placeholders);
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.interfaces.core;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ServerCore<F, P, P2> extends PluginCore<F>{
|
||||
List<P> createPlayers(List<String> lines, P2 player, Placeholders... placeholders);
|
||||
}
|
||||
+62
-8
@@ -1,25 +1,79 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.parsing;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ComponentParser{
|
||||
|
||||
private static final MiniMessage mm = MiniMessage.miniMessage();
|
||||
private static final LegacyComponentSerializer legacy = LegacyComponentSerializer.legacySection();
|
||||
private static final MiniMessage mm;
|
||||
private static final LegacyComponentSerializer legacy;
|
||||
|
||||
public static Component toComponent(String msg){
|
||||
return mm.deserialize(msg);
|
||||
static {
|
||||
mm = MiniMessage.miniMessage();
|
||||
legacy = LegacyComponentSerializer.legacySection();
|
||||
}
|
||||
|
||||
public static Component toComponent(List<String> lines){
|
||||
return toComponent(String.join("\n", lines));
|
||||
private String text;
|
||||
|
||||
private ComponentParser(String text){
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public static String toString(String msg){
|
||||
return legacy.serialize(toComponent(msg));
|
||||
public static ComponentParser text(String text){
|
||||
return new ComponentParser(text);
|
||||
}
|
||||
|
||||
public static ComponentParser list(List<String> lines){
|
||||
return new ComponentParser(String.join("\n", lines));
|
||||
}
|
||||
|
||||
public ComponentParser replacements(Placeholders placeholders){
|
||||
text = StringReplacer.replace(text, placeholders.getReplacements());
|
||||
return this;
|
||||
}
|
||||
|
||||
public ComponentParser modifyText(Function<String, String> function){
|
||||
this.text = function.apply(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Component toComponent(){
|
||||
return mm.deserialize(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return legacy.serialize(toComponent());
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
package ch.andre601.advancedserverlist.core.profiles;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.ProxyLogger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class ConditionHolder{
|
||||
|
||||
private final List<String> expressions = new ArrayList<>();
|
||||
|
||||
public ConditionHolder(List<String> expressions){
|
||||
if(expressions != null && !expressions.isEmpty())
|
||||
this.expressions.addAll(expressions);
|
||||
}
|
||||
|
||||
public boolean eval(int protocol, ProxyLogger logger){
|
||||
if(expressions.isEmpty())
|
||||
return true;
|
||||
|
||||
for(String expression : expressions){
|
||||
if(!parseExpression(expression, protocol, logger))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean parseExpression(String expression, int protocol, ProxyLogger logger){
|
||||
if(expression == null || expression.isEmpty())
|
||||
return true;
|
||||
|
||||
String newExpression = replacePlaceholders(expression, protocol);
|
||||
|
||||
char[] chars = newExpression.toCharArray();
|
||||
|
||||
StringBuilder left = new StringBuilder();
|
||||
StringBuilder operator = new StringBuilder();
|
||||
StringBuilder right = new StringBuilder();
|
||||
|
||||
boolean operatorFound = false;
|
||||
|
||||
for(int i = 0; i < chars.length; i++){
|
||||
char c = chars[i];
|
||||
|
||||
if(c == ' ')
|
||||
continue;
|
||||
|
||||
if((c != '<' && c != '>' && c != '=' && c != '!') || i + 1 >= chars.length){
|
||||
if(operatorFound){
|
||||
right.append(c);
|
||||
continue;
|
||||
}
|
||||
|
||||
left.append(c);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(operatorFound){
|
||||
logger.warn("Encountered second operator in condition! AdvancedServerList currently only supports one operator!");
|
||||
return false;
|
||||
}
|
||||
|
||||
operatorFound = true;
|
||||
|
||||
char next = chars[i + 1];
|
||||
if(c == '!' && next != '='){
|
||||
logger.warn("Invalid condition found. Expected '!=' but found '!" + next + "' in condition " + newExpression);
|
||||
return false;
|
||||
}
|
||||
|
||||
operator.append(c);
|
||||
i++;
|
||||
|
||||
if(c == '!' || ((c == '<' || c == '>') && next == '=')){
|
||||
operator.append(next);
|
||||
}
|
||||
}
|
||||
|
||||
if(left.isEmpty() || operator.isEmpty() || right.isEmpty()){
|
||||
logger.warn("Failed to evaluate condition. One part of the expression was empty!");
|
||||
return false;
|
||||
}
|
||||
|
||||
int leftInt = tryParse(left.toString());
|
||||
int rightInt = tryParse(right.toString());
|
||||
|
||||
return switch(operator.toString().toLowerCase(Locale.ROOT)){
|
||||
case ">" -> leftInt > rightInt;
|
||||
case ">=" -> leftInt >= rightInt;
|
||||
case "=" -> left.toString().equals(right.toString());
|
||||
case "!=" -> !left.toString().equals(right.toString());
|
||||
case "<" -> leftInt < rightInt;
|
||||
case "<=" -> leftInt <= rightInt;
|
||||
default -> false;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
private String replacePlaceholders(String expression, int protocol){
|
||||
char[] chars = expression.toCharArray();
|
||||
|
||||
StringBuilder builder = new StringBuilder(expression.length());
|
||||
StringBuilder placeholder = new StringBuilder();
|
||||
|
||||
for(int i = 0; i < chars.length; i++){
|
||||
char c = chars[i];
|
||||
|
||||
if(c != '{' || i + 1 >= chars.length){
|
||||
builder.append(c);
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean valid = false;
|
||||
|
||||
while(++i < chars.length){
|
||||
char p = chars[i];
|
||||
|
||||
if(p == ' ' || p == '<' || p == '>' || p == '=' || p == '!')
|
||||
break;
|
||||
|
||||
if(p == '}'){
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
|
||||
placeholder.append(p);
|
||||
}
|
||||
|
||||
String finalPlaceholder = placeholder.toString();
|
||||
|
||||
if(!valid){
|
||||
builder.append('{').append(finalPlaceholder);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(finalPlaceholder.equals("playerVersion")){
|
||||
builder.append(protocol);
|
||||
}else{
|
||||
builder.append('{').append(finalPlaceholder).append('}');
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private int tryParse(String value){
|
||||
try{
|
||||
return Integer.parseInt(value);
|
||||
}catch(NumberFormatException ex){
|
||||
return value.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ProfileManager{
|
||||
|
||||
private final AdvancedServerList core;
|
||||
|
||||
private final Map<String, Object> replacements = new HashMap<>();
|
||||
|
||||
private ProfileManager(AdvancedServerList core){
|
||||
this.core = core;
|
||||
}
|
||||
|
||||
public static ProfileManager get(AdvancedServerList core){
|
||||
return new ProfileManager(core);
|
||||
}
|
||||
|
||||
public ProfileManager replacements(Placeholders placeholders){
|
||||
this.replacements.putAll(placeholders.getReplacements());
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerListProfile getProfile(){
|
||||
for(ServerListProfile profile : core.getFileHandler().getProfiles()){
|
||||
if(profile.isInvalid())
|
||||
continue;
|
||||
|
||||
if(profile.evalConditions(replacements))
|
||||
return profile;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+110
-16
@@ -1,6 +1,32 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.ProxyLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.Expression;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
|
||||
@@ -11,24 +37,28 @@ import java.util.Map;
|
||||
|
||||
public class ServerListProfile{
|
||||
|
||||
private final ConditionHolder conditions;
|
||||
private final int priority;
|
||||
private final List<Expression> expressions;
|
||||
|
||||
private final List<String> motd;
|
||||
private final List<String> players;
|
||||
private final String playerCount;
|
||||
private final String favicon;
|
||||
private final boolean hidePlayers;
|
||||
private final boolean extraPlayersEnabled;
|
||||
private final int extraPlayers;
|
||||
|
||||
public ServerListProfile(ConfigurationNode node){
|
||||
this.conditions = new ConditionHolder(getList(node, "conditions"));
|
||||
public ServerListProfile(ConfigurationNode node, PluginLogger logger){
|
||||
this.priority = node.node("priority").getInt();
|
||||
this.expressions = createExpressions(getList(node, false, "conditions"), logger);
|
||||
|
||||
this.motd = getList(node, "motd");
|
||||
this.players = getList(node, "players");
|
||||
this.playerCount = node.node("playerCount").getString("");
|
||||
}
|
||||
|
||||
public ConditionHolder getConditions(){
|
||||
return conditions;
|
||||
this.motd = getList(node, true, "motd");
|
||||
this.players = getList(node, false, "playerCount", "hover");
|
||||
this.playerCount = node.node("playerCount", "text").getString("");
|
||||
this.favicon = node.node("favicon").getString("");
|
||||
this.hidePlayers = node.node("playerCount", "hidePlayers").getBoolean();
|
||||
this.extraPlayersEnabled = node.node("playerCount", "extraPlayers", "enabled").getBoolean();
|
||||
this.extraPlayers = node.node("playerCount", "extraPlayers", "amount").getInt();
|
||||
}
|
||||
|
||||
public int getPriority(){
|
||||
@@ -47,11 +77,75 @@ public class ServerListProfile{
|
||||
return playerCount;
|
||||
}
|
||||
|
||||
private List<String> getList(ConfigurationNode node, String key){
|
||||
try{
|
||||
return node.node(key).getList(String.class);
|
||||
}catch(SerializationException ex){
|
||||
return null;
|
||||
public String getFavicon(){
|
||||
return favicon;
|
||||
}
|
||||
|
||||
public boolean shouldHidePlayers(){
|
||||
return hidePlayers;
|
||||
}
|
||||
|
||||
public boolean isExtraPlayersEnabled(){
|
||||
return extraPlayersEnabled;
|
||||
}
|
||||
|
||||
public int getExtraPlayers(){
|
||||
return extraPlayers;
|
||||
}
|
||||
|
||||
public boolean evalConditions(Map<String, Object> replacements){
|
||||
if(expressions.isEmpty())
|
||||
return true;
|
||||
|
||||
for(Expression expression : expressions){
|
||||
if(!expression.evaluate(replacements)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isInvalid(){
|
||||
return getMotd().isEmpty() &&
|
||||
getPlayers().isEmpty() &&
|
||||
(getPlayerCount().isEmpty() && !shouldHidePlayers()) &&
|
||||
getFavicon().isEmpty();
|
||||
}
|
||||
|
||||
private List<Expression> createExpressions(List<String> list, PluginLogger logger) {
|
||||
if(list.isEmpty())
|
||||
return Collections.emptyList();
|
||||
|
||||
List<Expression> expressions = new ArrayList<>();
|
||||
for(String str : list){
|
||||
Expression expression = new Expression(str);
|
||||
|
||||
if(expression.getResult() != Expression.ExpressionResult.VALID){
|
||||
logger.warn("Detected Invalid condition '%s'! Cause: %s", str, expression.getResult().getMessage());
|
||||
continue;
|
||||
}
|
||||
|
||||
expressions.add(expression);
|
||||
}
|
||||
|
||||
return expressions;
|
||||
}
|
||||
|
||||
private List<String> getList(ConfigurationNode node, boolean trim, Object... path){
|
||||
List<String> list;
|
||||
try{
|
||||
list = node.node(path).getList(String.class);
|
||||
}catch(SerializationException ex){
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if(list == null)
|
||||
return Collections.emptyList();
|
||||
|
||||
if(trim && list.size() > 2)
|
||||
return list.subList(0, 2);
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class Expression{
|
||||
|
||||
private ExpressionResult result = ExpressionResult.VALID;
|
||||
|
||||
private String left;
|
||||
private Operator operator = Operator.UNKNOWN;
|
||||
private String right;
|
||||
|
||||
public Expression(String expression){
|
||||
resolveExpression(expression);
|
||||
}
|
||||
|
||||
public boolean evaluate(Map<String, Object> replacements){
|
||||
String newLeft = StringReplacer.replace(left, replacements).trim();
|
||||
String newRight = StringReplacer.replace(right, replacements).trim();
|
||||
|
||||
return operator.evaluate(newLeft, newRight);
|
||||
}
|
||||
|
||||
public ExpressionResult getResult(){
|
||||
return result;
|
||||
}
|
||||
|
||||
private void resolveExpression(String expression){
|
||||
if(expression == null || expression.isEmpty()){
|
||||
result = ExpressionResult.INVALID_NO_EXPRESSION;
|
||||
return;
|
||||
}
|
||||
|
||||
char[] chars = expression.toCharArray();
|
||||
|
||||
StringBuilder left = new StringBuilder();
|
||||
StringBuilder right = new StringBuilder();
|
||||
|
||||
boolean foundOperator = false;
|
||||
|
||||
for(int i = 0; i < chars.length; i++){
|
||||
char c = chars[i];
|
||||
char next = (i == (chars.length - 1)) ? '\0' : chars[i + 1];
|
||||
|
||||
Operator tmp = Operator.getOperand(c, next);
|
||||
if(tmp != Operator.UNKNOWN && !foundOperator){
|
||||
operator = tmp;
|
||||
foundOperator = true;
|
||||
|
||||
if(tmp.hasSecond())
|
||||
i++; // Skip next character if operator has 2
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if(foundOperator){
|
||||
right.append(c);
|
||||
}else{
|
||||
left.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
if(left.isEmpty() || right.isEmpty()){
|
||||
result = ExpressionResult.INVALID_EMPTY_PARTS;
|
||||
return;
|
||||
}
|
||||
|
||||
this.left = left.toString();
|
||||
this.right = right.toString();
|
||||
}
|
||||
|
||||
public enum Operator{
|
||||
LESS('<', '\0'){
|
||||
@Override
|
||||
public boolean evaluate(String left, String right){
|
||||
int leftInt = Operator.getInt(left);
|
||||
int rightInt = Operator.getInt(right);
|
||||
|
||||
return leftInt < rightInt;
|
||||
}
|
||||
},
|
||||
LESS_OR_EQUAL('<', '='){
|
||||
@Override
|
||||
public boolean evaluate(String left, String right){
|
||||
int leftInt = Operator.getInt(left);
|
||||
int rightInt = Operator.getInt(right);
|
||||
|
||||
return leftInt <= rightInt;
|
||||
}
|
||||
},
|
||||
EQUAL('=', '\0'){
|
||||
@Override
|
||||
public boolean evaluate(String left, String right){
|
||||
return left.equals(right);
|
||||
}
|
||||
},
|
||||
NOT_EQUAL('!', '='){
|
||||
@Override
|
||||
public boolean evaluate(String left, String right){
|
||||
return !left.equals(right);
|
||||
}
|
||||
},
|
||||
GREATER('>', '\0'){
|
||||
@Override
|
||||
public boolean evaluate(String left, String right){
|
||||
int leftInt = Operator.getInt(left);
|
||||
int rightInt = Operator.getInt(right);
|
||||
|
||||
return leftInt > rightInt;
|
||||
}
|
||||
},
|
||||
GREATER_OR_EQUAL('>', '='){
|
||||
@Override
|
||||
public boolean evaluate(String left, String right){
|
||||
int leftInt = Operator.getInt(left);
|
||||
int rightInt = Operator.getInt(right);
|
||||
|
||||
return leftInt >= rightInt;
|
||||
}
|
||||
},
|
||||
|
||||
UNKNOWN('\0', '\0'){
|
||||
@Override
|
||||
public boolean evaluate(String left, String right){
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
private static final Operator[] VALUES = values();
|
||||
|
||||
private final char first;
|
||||
private final char second;
|
||||
|
||||
Operator(char first, char second){
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
public static Operator getOperand(char first, char second){
|
||||
for(Operator operator : VALUES){
|
||||
if(operator.first == first){
|
||||
if((!operator.hasSecond() && second != '=') || operator.second == second)
|
||||
return operator;
|
||||
}
|
||||
}
|
||||
|
||||
return Operator.UNKNOWN;
|
||||
}
|
||||
|
||||
public boolean hasSecond(){
|
||||
return second != '\0';
|
||||
}
|
||||
|
||||
public abstract boolean evaluate(String left, String right);
|
||||
|
||||
private static int getInt(String text){
|
||||
try{
|
||||
return Integer.parseInt(text);
|
||||
}catch(NumberFormatException ex){
|
||||
return text.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ExpressionResult{
|
||||
VALID(null),
|
||||
|
||||
INVALID_NO_EXPRESSION ("Received empty condition which isn't allowed!"),
|
||||
INVALID_EMPTY_PARTS ("Received condition with either left or right part being empty.");
|
||||
|
||||
private final String message;
|
||||
|
||||
ExpressionResult(String message){
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage(){
|
||||
return message;
|
||||
}
|
||||
}
|
||||
}
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.favicon;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class FaviconHandler<F>{
|
||||
|
||||
private final Cache<String, F> favicons = Caffeine.newBuilder()
|
||||
.expireAfterWrite(5, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
private final AdvancedServerList core;
|
||||
|
||||
public FaviconHandler(AdvancedServerList core){
|
||||
this.core = core;
|
||||
}
|
||||
|
||||
public F getFavicon(String input, Function<BufferedImage, F> function){
|
||||
return favicons.get(input, k -> {
|
||||
BufferedImage image = resolveImage(core, input);
|
||||
if(image == null)
|
||||
return null;
|
||||
|
||||
return function.apply(image);
|
||||
});
|
||||
}
|
||||
|
||||
public void clearCache(){
|
||||
favicons.invalidateAll();
|
||||
}
|
||||
|
||||
private BufferedImage resolveImage(AdvancedServerList core, String input){
|
||||
InputStream stream;
|
||||
|
||||
if(input.toLowerCase(Locale.ROOT).startsWith("https://")){
|
||||
stream = getFromUrl(core, input);
|
||||
}else
|
||||
if(input.toLowerCase(Locale.ROOT).endsWith(".png")){
|
||||
File folder = core.getPlugin().getFolderPath().resolve("favicons").toFile();
|
||||
if(!folder.exists()){
|
||||
core.getPlugin().getPluginLogger().warn("Cannot get Favicon %s from favicons folder. Folder doesn't exist!", input);
|
||||
return null;
|
||||
}
|
||||
|
||||
File file = new File(folder, input);
|
||||
|
||||
try{
|
||||
stream = new FileInputStream(file);
|
||||
}catch(IOException ex){
|
||||
core.getPlugin().getPluginLogger().warn("Cannot create Favicon from File %s.", input);
|
||||
core.getPlugin().getPluginLogger().warn("Cause: %s", ex.getMessage());
|
||||
return null;
|
||||
}
|
||||
}else{
|
||||
stream = getFromUrl(core, "https://mc-heads.net/avatar/" + input + "/64");
|
||||
}
|
||||
|
||||
if(stream == null){
|
||||
core.getPlugin().getPluginLogger().warn("Cannot create Favicon. InputStream was null.");
|
||||
return null;
|
||||
}
|
||||
|
||||
try{
|
||||
BufferedImage original = ImageIO.read(stream);
|
||||
if(original == null){
|
||||
core.getPlugin().getPluginLogger().warn("Cannot create Favicon. Unable to create BufferedImage.");
|
||||
return null;
|
||||
}
|
||||
|
||||
BufferedImage favicon = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D img = favicon.createGraphics();
|
||||
|
||||
// Resize original image to 64x64 and apply to favicon.
|
||||
img.drawImage(original, 0, 0, 64, 64, null);
|
||||
img.dispose();
|
||||
|
||||
return favicon;
|
||||
}catch(IOException ex){
|
||||
core.getPlugin().getPluginLogger().warn("Unable to create Favicon. Encountered IOException during creation.");
|
||||
core.getPlugin().getPluginLogger().warn("Cause: %s", ex.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream getFromUrl(AdvancedServerList core, String url){
|
||||
try{
|
||||
URL faviconUrl = new URL(url);
|
||||
URLConnection connection = faviconUrl.openConnection();
|
||||
connection.setRequestProperty("User-Agent", "AdvancedServerList/" + core.getVersion());
|
||||
connection.connect();
|
||||
|
||||
return connection.getInputStream();
|
||||
}catch(IOException ex){
|
||||
core.getPlugin().getPluginLogger().warn("Error while connecting to %s for Favicon creation.", url);
|
||||
core.getPlugin().getPluginLogger().warn("Cause: %s", ex.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.players;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class GenericPlayer<T>{
|
||||
|
||||
protected T player = null;
|
||||
protected String name = null;
|
||||
protected String version = null;
|
||||
protected int protocol = -1;
|
||||
protected boolean playedBefore = false;
|
||||
protected boolean banned = false;
|
||||
protected boolean whitelisted = false;
|
||||
protected UUID uuid = null;
|
||||
|
||||
public T getPlayer(){
|
||||
return player;
|
||||
}
|
||||
|
||||
public String getName(){
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getProtocol(){
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public String getVersion(){
|
||||
return version;
|
||||
}
|
||||
|
||||
public boolean hasPlayedBefore(){
|
||||
return playedBefore;
|
||||
}
|
||||
|
||||
public boolean isBanned(){
|
||||
return banned;
|
||||
}
|
||||
|
||||
public boolean isWhitelisted(){
|
||||
return whitelisted;
|
||||
}
|
||||
|
||||
public UUID getUniqueId(){
|
||||
return uuid;
|
||||
}
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.players;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.EntryList;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class PlayerHandler{
|
||||
|
||||
private final AdvancedServerList core;
|
||||
private final Path cache;
|
||||
private final EntryList<String, String> players = new EntryList<>();
|
||||
|
||||
public PlayerHandler(AdvancedServerList core){
|
||||
this.core = core;
|
||||
this.cache = core.getPlugin().getFolderPath().resolve("cache.data");
|
||||
}
|
||||
|
||||
public void load(){
|
||||
if(!cache.toFile().exists()){
|
||||
core.getPlugin().getPluginLogger().info("No cache.data present. Skipping...");
|
||||
return;
|
||||
}
|
||||
List<String> lines;
|
||||
try{
|
||||
lines = Files.readAllLines(cache);
|
||||
}catch(IOException ex){
|
||||
core.getPlugin().getPluginLogger().warn("Encountered IOException while trying to read cache.data", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
if(lines.isEmpty()){
|
||||
core.getPlugin().getPluginLogger().info("cache.data is empty. Skipping...");
|
||||
return;
|
||||
}
|
||||
|
||||
for(String line : lines){
|
||||
String[] parts = line.split("=", 2);
|
||||
if(parts.length < 2 || parts[0].isEmpty() || parts[1].isEmpty())
|
||||
continue;
|
||||
|
||||
if(players.containsKey(parts[0]))
|
||||
continue;
|
||||
|
||||
players.add(parts[0], parts[1]);
|
||||
}
|
||||
|
||||
core.getPlugin().getPluginLogger().info("Loaded " + players.size() + " players into cache!");
|
||||
}
|
||||
|
||||
public void save(){
|
||||
if(players.isEmpty()){
|
||||
core.getPlugin().getPluginLogger().info("No data to save. Skipping...");
|
||||
return;
|
||||
}
|
||||
|
||||
StringJoiner joiner = new StringJoiner("\n");
|
||||
for(Map.Entry<String, String> entry : players){
|
||||
joiner.add(entry.getKey() + "=" + entry.getValue());
|
||||
}
|
||||
|
||||
try{
|
||||
BufferedWriter writer = Files.newBufferedWriter(cache, StandardCharsets.UTF_8, StandardOpenOption.WRITE);
|
||||
|
||||
writer.write(joiner.toString());
|
||||
writer.close();
|
||||
|
||||
core.getPlugin().getPluginLogger().info("Successfully saved cache.data file.");
|
||||
}catch(IOException ex){
|
||||
core.getPlugin().getPluginLogger().warn("Cannot save player data to cache.data file!", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void addPlayer(String name, String ip){
|
||||
if(players.containsKey(name))
|
||||
return;
|
||||
|
||||
players.add(name, ip);
|
||||
}
|
||||
|
||||
public String getPlayerByIp(String ip){
|
||||
for(Map.Entry<String, String> entry : players){
|
||||
if(entry.getValue().equals(ip))
|
||||
return entry.getKey();
|
||||
}
|
||||
|
||||
return core.getFileHandler().getString("Anonymous", "unknown_player");
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.replacer;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
* Original by Imo van den Berge (aka Bergerkiller: https://github.com/Bergerkiller)
|
||||
*
|
||||
* Original Source: https://github.com/bergerhealer/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/collections/EntryList.java
|
||||
*/
|
||||
public class EntryList<K, V> extends ArrayList<Map.Entry<K, V>>{
|
||||
public void add(K key, V value){
|
||||
add(new AbstractMap.SimpleEntry<>(key, value));
|
||||
}
|
||||
|
||||
public boolean containsKey(K key){
|
||||
for(Map.Entry<K, V> entry : this){
|
||||
if(entry.getKey().equals(key))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.replacer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class StringReplacer{
|
||||
|
||||
public static String replace(String input, Map<String, Object> replacements){
|
||||
StringBuilder output = new StringBuilder(input);
|
||||
int index;
|
||||
for(Map.Entry<String, Object> entry : replacements.entrySet()){
|
||||
index = 0;
|
||||
while((index = output.indexOf(entry.getKey(), index)) != -1){
|
||||
output.replace(index, index + entry.getKey().length(), String.valueOf(entry.getValue()));
|
||||
index += String.valueOf(entry.getValue()).length();
|
||||
}
|
||||
}
|
||||
return output.toString();
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.replacer.placeholders;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface Placeholders{
|
||||
|
||||
Map<String, Object> getReplacements();
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.replacer.placeholders;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PlayerPlaceholders implements Placeholders{
|
||||
|
||||
private final Map<String, Object> replacements = new HashMap<>();
|
||||
|
||||
public PlayerPlaceholders(GenericPlayer<?> player){
|
||||
this.replacements.put("${player name}", player.getName());
|
||||
this.replacements.put("${player protocol}", player.getProtocol());
|
||||
|
||||
if(player.getVersion() != null)
|
||||
this.replacements.put("${player version}", player.getVersion());
|
||||
|
||||
if(player.getPlayer() == null)
|
||||
return;
|
||||
|
||||
this.replacements.put("${player hasPlayedBefore}", player.hasPlayedBefore());
|
||||
this.replacements.put("${player isBanned}", player.isBanned());
|
||||
this.replacements.put("${player isWhitelisted}", player.isWhitelisted());
|
||||
this.replacements.put("${player uuid}", player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getReplacements(){
|
||||
return replacements;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.replacer.placeholders;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ServerPlaceholders implements Placeholders{
|
||||
|
||||
private final Map<String, Object> replacements = new HashMap<>();
|
||||
|
||||
public ServerPlaceholders(int online, int max, String host){
|
||||
this.replacements.put("${server playersOnline}", online);
|
||||
this.replacements.put("${server playersMax}", max);
|
||||
|
||||
if(host != null)
|
||||
this.replacements.put("${server host}", host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getReplacements(){
|
||||
return this.replacements;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#
|
||||
# Used for when AdvancedServerList doesn't have a cached player to use for ${player name}
|
||||
#
|
||||
unknown_player: "Anonymous"
|
||||
@@ -17,29 +17,90 @@ priority: 0
|
||||
|
||||
#
|
||||
# Set the MOTD that should be displayed.
|
||||
# Can be removed or set to "motd: []" to not alter the MOTD.
|
||||
# Supports HEX colors for 1.16+ servers including gradients using MiniMessage's <gradient:color:color> format.
|
||||
#
|
||||
# Remove this option or set it to motd: [] to not alter the MOTD.
|
||||
#
|
||||
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#motd
|
||||
#
|
||||
motd:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
- '<grey>Line 1'
|
||||
- '<grey>Line 2'
|
||||
|
||||
#
|
||||
# Set the hover text that usually displays online players.
|
||||
# Can be removed or set to "players: []" to not alter the player list.
|
||||
# Allows you to set a favicon for this server list profile.
|
||||
# You can use one of three possible options:
|
||||
# 1. A file name matching a PNG file located in the 'favicons' folder (Needs to end with .png)
|
||||
# 2. A URL pointing to a valid Image
|
||||
# 3. ${player name} to display the player's head as favicon. Uses https://mc-heads.net for this
|
||||
#
|
||||
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#players
|
||||
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#favicon
|
||||
#
|
||||
players:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
- 'Line 3'
|
||||
favicon: ''
|
||||
|
||||
#
|
||||
# Set the text that usually shows online players and max that can join.
|
||||
# Can be removed or set to "playerCount: ''" to not alter the player count text.
|
||||
# Contains various options to manipulate the player count (Text displaying online and max players allowed).
|
||||
#
|
||||
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#playercount
|
||||
#
|
||||
playerCount: 'Text'
|
||||
playerCount:
|
||||
#
|
||||
# Whether AdvancedServerList should hide the player count or not.
|
||||
# When set to true will the player count display '???' instead of <online>/<max>
|
||||
#
|
||||
# Note that when this is enabled will all other options, except for 'extraPlayers', be ignored.
|
||||
#
|
||||
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#hideplayers
|
||||
#
|
||||
hidePlayers: false
|
||||
#
|
||||
# Sets the text displayed when hovering over the player count.
|
||||
# You can set this to 'hover: []' or remove the option to not modify the hover text.
|
||||
#
|
||||
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#hover
|
||||
#
|
||||
hover:
|
||||
- '<grey>Line 1'
|
||||
- '<grey>Line 2'
|
||||
- '<grey>Line 3'
|
||||
#
|
||||
# Modifies the text that usually displays '<online>/<max>'
|
||||
#
|
||||
# Note that when used, the Ping icon will display as 'outdated server'/'outdated client'.
|
||||
# This is nothing that can be fixed or avoided and would require changes from Mojang.
|
||||
#
|
||||
# You can set this to 'count: ''' or remove the option to not modify the player count text.
|
||||
#
|
||||
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#text
|
||||
#
|
||||
text: ''
|
||||
#
|
||||
# Allows you to modify the max player count displayed.
|
||||
# Note that this will affect ${server playersMax} (Except for when used in conditions).
|
||||
#
|
||||
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#extraPlayers
|
||||
#
|
||||
extraPlayers:
|
||||
#
|
||||
# Enables/Disables the extraPlayers option.
|
||||
# When enabled will the total amount of players allowed be modified to the current
|
||||
# number of online players + 'amount'
|
||||
#
|
||||
# Defaults to false when not present.
|
||||
#
|
||||
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#enabled
|
||||
#
|
||||
enabled: false
|
||||
#
|
||||
# Sets how much should be added/subtracted from the current number of online players
|
||||
# to then use for the max player count.
|
||||
#
|
||||
# Example:
|
||||
# When set to 1 while 10 players are online would the player count - if unmodified -
|
||||
# display '10/11'. When -1 is used will it display '10/9'
|
||||
#
|
||||
# Defaults to 0 when not present.
|
||||
#
|
||||
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#amount
|
||||
#
|
||||
amount: 0
|
||||
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2022 Andre_601
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
#
|
||||
|
||||
version=${plugin.version}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ MIT License
|
||||
~
|
||||
~ Copyright (c) 2022 Andre_601
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in all
|
||||
~ copies or substantial portions of the Software.
|
||||
~
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
~ SOFTWARE.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>ch.andre601.advancedserverlist</groupId>
|
||||
<version>parent</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>paper</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>${plugin.version}</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>16</maven.compiler.source>
|
||||
<maven.compiler.target>16</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>papermc</id>
|
||||
<url>https://papermc.io/repo/repository/maven-public</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>placeholderapi-repo</id>
|
||||
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.advancedserverlist</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>${plugin.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>1.19-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.clip</groupId>
|
||||
<artifactId>placeholderapi</artifactId>
|
||||
<version>2.11.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>AdvancedServerList-Paper-${plugin.version}</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${project.basedir}/src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.10.1</version>
|
||||
<configuration>
|
||||
<release>16</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.4.0</version>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.spongepowered.configurate</pattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.paper.depends.configurate</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.bstats</pattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.paper.depends.bstats</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.github.benmanes.caffeine</pattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.paper.depends.caffeine</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.paper;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.ServerCore;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
import ch.andre601.advancedserverlist.paper.commands.CmdAdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.paper.events.JoinEvent;
|
||||
import ch.andre601.advancedserverlist.paper.events.PingEvent;
|
||||
import ch.andre601.advancedserverlist.paper.logging.PaperLogger;
|
||||
import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bstats.charts.SimplePie;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.CachedServerIcon;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PaperCore extends JavaPlugin implements ServerCore<CachedServerIcon, PlayerProfile, OfflinePlayer>{
|
||||
|
||||
private final PluginLogger logger = new PaperLogger(getLogger());
|
||||
|
||||
private AdvancedServerList core;
|
||||
private FaviconHandler<CachedServerIcon> faviconHandler;
|
||||
|
||||
@Override
|
||||
public void onEnable(){
|
||||
try{
|
||||
Class.forName("io.papermc.paper.configuration.ConfigurationLoaders");
|
||||
enable();
|
||||
}catch(ClassNotFoundException ex){
|
||||
try{
|
||||
Class.forName("com.destroystokyo.paper.PaperConfig");
|
||||
enable();
|
||||
}catch(ClassNotFoundException ex1){
|
||||
getPluginLogger().warn("======================================== WARNING ========================================");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("You are using the PaperMC version of AdvancedServerList on a SpigotMC server.");
|
||||
getPluginLogger().warn("The PaperMC version is ONLY compatible with PaperMC itself due to it using exclusive");
|
||||
getPluginLogger().warn("methods and events not available within SpigotMC.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("To avoid any exceptions and errors will AdvancedServerList disable itself now.");
|
||||
getPluginLogger().warn("Please stop your server and either switch to PaperMC or use the Spigot version");
|
||||
getPluginLogger().warn("of AdvancedServerList.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("======================================== WARNING ========================================");
|
||||
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable(){
|
||||
if(getCore() == null)
|
||||
return; // This is always the case when the plugin is used on a Spigot server (See above try-catch blocks).
|
||||
|
||||
getCore().disable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCommands(){
|
||||
PluginCommand cmd = getServer().getPluginCommand("advancedserverlist");
|
||||
if(cmd == null){
|
||||
getPluginLogger().warn("Could not register command /advancedserverlist");
|
||||
return;
|
||||
}
|
||||
cmd.setExecutor(new CmdAdvancedServerList(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadEvents(){
|
||||
new JoinEvent(this);
|
||||
new PingEvent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMetrics(){
|
||||
new Metrics(this, 15584).addCustomChart(new SimplePie("profiles",
|
||||
() -> String.valueOf(core.getFileHandler().getProfiles().size())
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearFaviconCache(){
|
||||
if(faviconHandler == null)
|
||||
return;
|
||||
|
||||
faviconHandler.clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdvancedServerList getCore(){
|
||||
return core;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getFolderPath(){
|
||||
return getDataFolder().toPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginLogger getPluginLogger(){
|
||||
return logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaviconHandler<CachedServerIcon> getFaviconHandler(){
|
||||
if(faviconHandler == null)
|
||||
faviconHandler = new FaviconHandler<>(core);
|
||||
|
||||
return faviconHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlatformName(){
|
||||
return getServer().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlatformVersion(){
|
||||
return getServer().getVersion();
|
||||
}
|
||||
|
||||
private void enable(){
|
||||
this.core = new AdvancedServerList(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PlayerProfile> createPlayers(List<String> lines, OfflinePlayer player, Placeholders... placeholders){
|
||||
List<PlayerProfile> players = new ArrayList<>(lines.size());
|
||||
|
||||
for(String line : lines){
|
||||
String parsed = ComponentParser.text(line)
|
||||
.replacements(placeholders[0])
|
||||
.replacements(placeholders[1])
|
||||
.modifyText(text -> {
|
||||
if(getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
return PlaceholderAPI.setPlaceholders(player, text);
|
||||
|
||||
return text;
|
||||
})
|
||||
.toString();
|
||||
|
||||
players.add(Bukkit.createProfile(UUID.randomUUID(), parsed));
|
||||
}
|
||||
|
||||
return players;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.paper;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
public class PaperPlayer extends GenericPlayer<OfflinePlayer>{
|
||||
|
||||
public PaperPlayer(OfflinePlayer player, String name, int protocol){
|
||||
this.player = player;
|
||||
|
||||
this.name = player == null ? name : player.getName();
|
||||
this.protocol = protocol;
|
||||
|
||||
if(player == null)
|
||||
return;
|
||||
|
||||
this.playedBefore = player.hasPlayedBefore();
|
||||
this.banned = player.isBanned();
|
||||
this.whitelisted = player.isWhitelisted();
|
||||
this.uuid = player.getUniqueId();
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.paper.commands;
|
||||
|
||||
import ch.andre601.advancedserverlist.paper.PaperCore;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CmdAdvancedServerList implements CommandExecutor{
|
||||
|
||||
private final PaperCore plugin;
|
||||
|
||||
public CmdAdvancedServerList(PaperCore plugin){
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, @NotNull String[] args){
|
||||
plugin.getCore().getCommandHandler().handle(new PaperCmdSender(sender), args);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.paper.commands;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.CmdSender;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class PaperCmdSender implements CmdSender{
|
||||
|
||||
private final CommandSender sender;
|
||||
|
||||
public PaperCmdSender(CommandSender sender){
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String permission){
|
||||
return sender.hasPermission(permission) || sender.hasPermission("advancedserverlist.admin");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMsg(String msg, Object... args){
|
||||
sender.sendMessage(ComponentParser.text(String.format(msg, args)).toComponent());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.paper.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.paper.PaperCore;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public class JoinEvent implements Listener{
|
||||
|
||||
private final PaperCore plugin;
|
||||
|
||||
public JoinEvent(PaperCore plugin){
|
||||
this.plugin = plugin;
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent event){
|
||||
InetSocketAddress address = event.getPlayer().getAddress();
|
||||
if(address == null)
|
||||
return;
|
||||
|
||||
plugin.getCore().getPlayerHandler().addPlayer(event.getPlayer().getName(), address.getHostString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.paper.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ProfileManager;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.paper.PaperCore;
|
||||
import ch.andre601.advancedserverlist.paper.PaperPlayer;
|
||||
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.util.CachedServerIcon;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public class PingEvent implements Listener{
|
||||
|
||||
private final PaperCore plugin;
|
||||
|
||||
public PingEvent(PaperCore plugin){
|
||||
this.plugin = plugin;
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onServerPing(PaperServerListPingEvent event){
|
||||
InetSocketAddress address = event.getClient().getAddress();
|
||||
InetSocketAddress host = event.getClient().getVirtualHost();
|
||||
|
||||
PaperPlayer player = resolvePlayer(address, event.getClient().getProtocolVersion());
|
||||
|
||||
int online = event.getNumPlayers();
|
||||
int max = event.getMaxPlayers();
|
||||
|
||||
PlayerPlaceholders playerPlaceholders = new PlayerPlaceholders(player);
|
||||
ServerPlaceholders serverPlaceholders = new ServerPlaceholders(online, max, host == null ? null : host.getHostString());
|
||||
|
||||
ServerListProfile profile = ProfileManager.get(plugin.getCore())
|
||||
.replacements(playerPlaceholders)
|
||||
.replacements(serverPlaceholders)
|
||||
.getProfile();
|
||||
|
||||
if(profile == null)
|
||||
return;
|
||||
|
||||
if(profile.isExtraPlayersEnabled()){
|
||||
max = online + profile.getExtraPlayers();
|
||||
event.setMaxPlayers(max);
|
||||
}
|
||||
|
||||
serverPlaceholders = new ServerPlaceholders(online, max, host == null ? null : host.getHostString());
|
||||
|
||||
if(!profile.getMotd().isEmpty()){
|
||||
event.motd(ComponentParser.list(profile.getMotd())
|
||||
.replacements(playerPlaceholders)
|
||||
.replacements(serverPlaceholders)
|
||||
.modifyText(text -> {
|
||||
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
|
||||
|
||||
return text;
|
||||
})
|
||||
.toComponent());
|
||||
}
|
||||
|
||||
if(profile.shouldHidePlayers()){
|
||||
event.setHidePlayers(true);
|
||||
}
|
||||
|
||||
if(!profile.getPlayerCount().isEmpty() && !profile.shouldHidePlayers()){
|
||||
event.setVersion(ComponentParser.text(profile.getPlayerCount())
|
||||
.replacements(playerPlaceholders)
|
||||
.replacements(serverPlaceholders)
|
||||
.modifyText(text -> {
|
||||
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
|
||||
|
||||
return text;
|
||||
})
|
||||
.toString());
|
||||
event.setProtocolVersion(-1);
|
||||
}
|
||||
|
||||
if(!profile.getPlayers().isEmpty() && !profile.shouldHidePlayers()){
|
||||
event.getPlayerSample().clear();
|
||||
|
||||
event.getPlayerSample().addAll(
|
||||
plugin.createPlayers(profile.getPlayers(), player.getPlayer(), playerPlaceholders, serverPlaceholders)
|
||||
);
|
||||
}
|
||||
|
||||
if(!profile.getFavicon().isEmpty()){
|
||||
String favName = StringReplacer.replace(profile.getFavicon(), playerPlaceholders.getReplacements());
|
||||
|
||||
CachedServerIcon favicon = plugin.getFaviconHandler().getFavicon(favName, image -> {
|
||||
try{
|
||||
return Bukkit.loadServerIcon(image);
|
||||
}catch(Exception ex){
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
if(favicon == null){
|
||||
plugin.getPluginLogger().warn("Could not obtain valid Favicon to use.");
|
||||
event.setServerIcon(event.getServerIcon());
|
||||
}else{
|
||||
event.setServerIcon(favicon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private PaperPlayer resolvePlayer(InetSocketAddress address, int protocol){
|
||||
String playerName = plugin.getCore().getPlayerHandler().getPlayerByIp(address.getHostString());
|
||||
OfflinePlayer player = Bukkit.getPlayerExact(playerName);
|
||||
|
||||
if(player == null){
|
||||
player = Bukkit.getOfflinePlayer(playerName);
|
||||
|
||||
return new PaperPlayer(player.hasPlayedBefore() ? player : null, playerName, protocol);
|
||||
}
|
||||
|
||||
return new PaperPlayer(player, playerName, protocol);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.paper.logging;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class PaperLogger implements PluginLogger{
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
public PaperLogger(Logger logger){
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String msg, Object... args){
|
||||
logger.info(String.format(msg, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Object... args){
|
||||
logger.warning(String.format(msg, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable throwable){
|
||||
logger.log(Level.WARNING, msg, throwable);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
name: 'AdvancedServerList'
|
||||
author: 'Andre_601'
|
||||
version: '${plugin.version}'
|
||||
description: '${plugin.description}'
|
||||
|
||||
main: 'ch.andre601.advancedserverlist.paper.PaperCore'
|
||||
|
||||
api-version: 1.19
|
||||
|
||||
softdepend:
|
||||
- 'PlaceholderAPI'
|
||||
|
||||
commands:
|
||||
advancedserverlist:
|
||||
description: 'Main command of AdvancedServerList'
|
||||
usage: '/<command> [help|reload]'
|
||||
aliases:
|
||||
- 'asl'
|
||||
permission: 'advancedserverlist.admin'
|
||||
|
||||
permissions:
|
||||
advancedserverlist.*:
|
||||
description: 'Grants access to all permissions'
|
||||
default: op
|
||||
children:
|
||||
- 'advancedserverlist.admin'
|
||||
advancedserverlist.admin:
|
||||
description: 'Grants access to all permissions'
|
||||
default: op
|
||||
children:
|
||||
- 'advancedserverlist.command.*'
|
||||
advancedserverlist.command.*:
|
||||
description: 'Grants access to all commands'
|
||||
default: op
|
||||
children:
|
||||
- 'advancedserverlist.command.help'
|
||||
- 'advancedserverlist.command.reload'
|
||||
advancedserverlist.command.help:
|
||||
description: 'Grants access to /asl help'
|
||||
default: op
|
||||
advancedserverlist.command.reload:
|
||||
description: 'Grants access to /asl reload'
|
||||
default: op
|
||||
@@ -12,7 +12,7 @@
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
<plugin.version>1.0.0</plugin.version>
|
||||
<plugin.version>1.6.2</plugin.version>
|
||||
<plugin.description>Create multiple Server lists based on conditions.</plugin.description>
|
||||
|
||||
<maven.compiler.source>16</maven.compiler.source>
|
||||
@@ -23,6 +23,8 @@
|
||||
<module>core</module>
|
||||
<module>velocity</module>
|
||||
<module>bungeecord</module>
|
||||
<module>paper</module>
|
||||
<module>spigot</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ MIT License
|
||||
~
|
||||
~ Copyright (c) 2022 Andre_601
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in all
|
||||
~ copies or substantial portions of the Software.
|
||||
~
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
~ SOFTWARE.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>ch.andre601.advancedserverlist</groupId>
|
||||
<version>parent</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spigot</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>${plugin.version}</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>16</maven.compiler.source>
|
||||
<maven.compiler.target>16</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spigot</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>protocollib-repo</id>
|
||||
<url>https://repo.dmulloy2.net/repository/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>placeholderapi-repo</id>
|
||||
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.advancedserverlist</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>${plugin.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.19-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-platform-bukkit</artifactId>
|
||||
<version>4.1.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib</artifactId>
|
||||
<version>4.8.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.clip</groupId>
|
||||
<artifactId>placeholderapi</artifactId>
|
||||
<version>2.11.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>AdvancedServerList-Spigot-${plugin.version}</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${project.basedir}/src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.10.1</version>
|
||||
<configuration>
|
||||
<release>16</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.4.0</version>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.bstats</pattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.spigot.depends.bstats</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.github.benmanes.caffeine</pattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.spigot.depends.caffeine</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.spigot;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.ServerCore;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
import ch.andre601.advancedserverlist.spigot.commands.CmdAdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.spigot.events.LoadEvent;
|
||||
import ch.andre601.advancedserverlist.spigot.logging.SpigotLogger;
|
||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
import com.comphenix.protocol.wrappers.WrappedServerPing;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bstats.charts.SimplePie;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SpigotCore extends JavaPlugin implements ServerCore<WrappedServerPing.CompressedImage, WrappedGameProfile, OfflinePlayer>{
|
||||
|
||||
private final PluginLogger logger = new SpigotLogger(getLogger());
|
||||
|
||||
private AdvancedServerList core;
|
||||
FaviconHandler<WrappedServerPing.CompressedImage> faviconHandler = null;
|
||||
|
||||
@Override
|
||||
public void onEnable(){
|
||||
try{
|
||||
Class.forName("io.papermc.paper.configuration.ConfigurationLoaders");
|
||||
|
||||
printPaperInfo();
|
||||
}catch(ClassNotFoundException ex){
|
||||
try{
|
||||
// Above class only exists since 1.19+, so this is a fallback for older versions.
|
||||
Class.forName("com.destroystokyo.paper.PaperConfig");
|
||||
|
||||
printPaperInfo();
|
||||
}catch(ClassNotFoundException ignored){}
|
||||
}
|
||||
|
||||
this.core = new AdvancedServerList(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable(){
|
||||
getCore().disable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCommands(){
|
||||
PluginCommand cmd = getServer().getPluginCommand("advancedserverlist");
|
||||
if(cmd == null){
|
||||
getPluginLogger().warn("Could not register command /advancedserverlist");
|
||||
return;
|
||||
}
|
||||
cmd.setExecutor(new CmdAdvancedServerList(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadEvents(){
|
||||
new LoadEvent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMetrics(){
|
||||
new Metrics(this, 15584).addCustomChart(new SimplePie("profiles",
|
||||
() -> String.valueOf(core.getFileHandler().getProfiles().size())
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearFaviconCache(){
|
||||
if(faviconHandler == null)
|
||||
return;
|
||||
|
||||
faviconHandler.clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdvancedServerList getCore(){
|
||||
return core;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getFolderPath(){
|
||||
return getDataFolder().toPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginLogger getPluginLogger(){
|
||||
return logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaviconHandler<WrappedServerPing.CompressedImage> getFaviconHandler(){
|
||||
if(faviconHandler == null)
|
||||
faviconHandler = new FaviconHandler<>(core);
|
||||
|
||||
return faviconHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlatformName(){
|
||||
return getServer().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlatformVersion(){
|
||||
return getServer().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WrappedGameProfile> createPlayers(List<String> lines, OfflinePlayer player, Placeholders... placeholders){
|
||||
List<WrappedGameProfile> players = new ArrayList<>(lines.size());
|
||||
|
||||
for(String line : lines){
|
||||
String parsed = ComponentParser.text(line)
|
||||
.replacements(placeholders[0])
|
||||
.replacements(placeholders[1])
|
||||
.modifyText(text -> {
|
||||
if(getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
return PlaceholderAPI.setPlaceholders(player, text);
|
||||
|
||||
return text;
|
||||
})
|
||||
.toString();
|
||||
|
||||
players.add(new WrappedGameProfile(UUID.randomUUID(), parsed));
|
||||
}
|
||||
|
||||
return players;
|
||||
}
|
||||
|
||||
private void printPaperInfo(){
|
||||
getPluginLogger().warn("======================================================================================");
|
||||
getPluginLogger().warn("You are using the Spigot version of AdvancedServerList on a Paper server.");
|
||||
getPluginLogger().warn("It is recommended to use the dedicated Paper version, to benefit from the");
|
||||
getPluginLogger().warn("following improvements:");
|
||||
getPluginLogger().warn(" - No need to download external libraries already provided by PaperMC.");
|
||||
getPluginLogger().warn(" - No dependency on ProtocolLib thanks to provided Events.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("AdvancedServerList may work as normal, but consider using the PaperMC version instead!");
|
||||
getPluginLogger().warn("======================================================================================");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.spigot;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
public class SpigotPlayer extends GenericPlayer<OfflinePlayer>{
|
||||
|
||||
public SpigotPlayer(OfflinePlayer player, String name, int protocol){
|
||||
this.player = player;
|
||||
|
||||
this.name = player == null ? name : player.getName();
|
||||
this.protocol = protocol;
|
||||
|
||||
if(player == null)
|
||||
return;
|
||||
|
||||
this.playedBefore = player.hasPlayedBefore();
|
||||
this.banned = player.isBanned();
|
||||
this.whitelisted = player.isWhitelisted();
|
||||
this.uuid = player.getUniqueId();
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.spigot.commands;
|
||||
|
||||
import ch.andre601.advancedserverlist.spigot.SpigotCore;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CmdAdvancedServerList implements CommandExecutor{
|
||||
|
||||
SpigotCore plugin;
|
||||
BukkitAudiences bukkitAudiences;
|
||||
|
||||
public CmdAdvancedServerList(SpigotCore plugin){
|
||||
this.plugin = plugin;
|
||||
bukkitAudiences = BukkitAudiences.create(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, @NotNull String[] args){
|
||||
plugin.getCore().getCommandHandler().handle(new SpigotCmdSender(sender, bukkitAudiences), args);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.spigot.commands;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.CmdSender;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class SpigotCmdSender implements CmdSender{
|
||||
|
||||
private final CommandSender sender;
|
||||
private final BukkitAudiences bukkitAudiences;
|
||||
|
||||
public SpigotCmdSender(CommandSender sender, BukkitAudiences bukkitAudiences){
|
||||
this.sender = sender;
|
||||
this.bukkitAudiences = bukkitAudiences;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String permission){
|
||||
return sender.hasPermission(permission) || sender.hasPermission("advancedserverlist.admin");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMsg(String msg, Object... args){
|
||||
bukkitAudiences.sender(sender).sendMessage(ComponentParser.text(String.format(msg, args)).toComponent());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.spigot.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.spigot.SpigotCore;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public class JoinEvent implements Listener{
|
||||
|
||||
private final SpigotCore plugin;
|
||||
|
||||
public JoinEvent(SpigotCore plugin){
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent event){
|
||||
InetSocketAddress address = event.getPlayer().getAddress();
|
||||
if(address == null)
|
||||
return;
|
||||
|
||||
plugin.getCore().getPlayerHandler().addPlayer(event.getPlayer().getName(), address.getHostString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.spigot.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.spigot.SpigotCore;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.ServerLoadEvent;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
public class LoadEvent implements Listener{
|
||||
|
||||
private final SpigotCore plugin;
|
||||
|
||||
public LoadEvent(SpigotCore plugin){
|
||||
this.plugin = plugin;
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onServerLoad(ServerLoadEvent event){
|
||||
PluginManager manager = plugin.getServer().getPluginManager();
|
||||
|
||||
if(!manager.isPluginEnabled("ProtocolLib")){
|
||||
plugin.getCore().getPlugin().getPluginLogger().warn("ProtocolLib not found! AdvancedServerList requires it to work on Spigot!");
|
||||
|
||||
manager.disablePlugin(plugin);
|
||||
return;
|
||||
}
|
||||
|
||||
manager.registerEvents(new JoinEvent(plugin), plugin);
|
||||
manager.registerEvents(new PingEvent(plugin, ProtocolLibrary.getProtocolManager()), plugin);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.spigot.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ProfileManager;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.spigot.SpigotCore;
|
||||
import ch.andre601.advancedserverlist.spigot.SpigotPlayer;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.wrappers.AdventureComponentConverter;
|
||||
import com.comphenix.protocol.wrappers.WrappedServerPing;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.*;
|
||||
|
||||
public class PingEvent implements Listener{
|
||||
|
||||
private final SpigotCore plugin;
|
||||
private final ProtocolManager protocolManager;
|
||||
|
||||
private final Map<String, String> hostAddresses = new HashMap<>();
|
||||
|
||||
public PingEvent(SpigotCore plugin, ProtocolManager protocolManager){
|
||||
this.plugin = plugin;
|
||||
this.protocolManager = protocolManager;
|
||||
|
||||
loadPacketListener(plugin);
|
||||
}
|
||||
|
||||
private void loadPacketListener(SpigotCore spigotPlugin){
|
||||
protocolManager.addPacketListener(new PacketAdapter(spigotPlugin, ListenerPriority.LOW, PacketType.Handshake.Client.SET_PROTOCOL){
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event){
|
||||
InetSocketAddress address = event.getPlayer().getAddress();
|
||||
if(address == null)
|
||||
return;
|
||||
|
||||
String host = event.getPacket().getStrings().read(0);
|
||||
|
||||
hostAddresses.put(address.getHostString(), host);
|
||||
}
|
||||
});
|
||||
|
||||
protocolManager.addPacketListener(new PacketAdapter(spigotPlugin, ListenerPriority.LOW, PacketType.Status.Server.SERVER_INFO){
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event){
|
||||
WrappedServerPing ping = event.getPacket().getServerPings().read(0);
|
||||
InetSocketAddress address = event.getPlayer().getAddress();
|
||||
if(address == null)
|
||||
return;
|
||||
|
||||
SpigotPlayer player = resolvePlayer(address, ping.getVersionProtocol());
|
||||
|
||||
int online = ping.getPlayersOnline();
|
||||
int max = ping.getPlayersMaximum();
|
||||
|
||||
PlayerPlaceholders playerPlaceholders = new PlayerPlaceholders(player);
|
||||
ServerPlaceholders serverPlaceholders = new ServerPlaceholders(online, max, hostAddresses.get(address.getHostString()));
|
||||
|
||||
ServerListProfile profile = ProfileManager.get(spigotPlugin.getCore())
|
||||
.replacements(playerPlaceholders)
|
||||
.replacements(serverPlaceholders)
|
||||
.getProfile();
|
||||
|
||||
if(profile == null)
|
||||
return;
|
||||
|
||||
if(profile.isExtraPlayersEnabled()){
|
||||
max = online + profile.getExtraPlayers();
|
||||
ping.setPlayersMaximum(max);
|
||||
}
|
||||
|
||||
serverPlaceholders = new ServerPlaceholders(online, max, hostAddresses.get(address.getHostString()));
|
||||
|
||||
if(!profile.getMotd().isEmpty()){
|
||||
Component component = ComponentParser.list(profile.getMotd())
|
||||
.replacements(playerPlaceholders)
|
||||
.replacements(serverPlaceholders)
|
||||
.modifyText(text -> {
|
||||
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
|
||||
|
||||
return text;
|
||||
})
|
||||
.toComponent();
|
||||
ping.setMotD(AdventureComponentConverter.fromComponent(component));
|
||||
}
|
||||
|
||||
if(profile.shouldHidePlayers()){
|
||||
ping.setPlayersVisible(false);
|
||||
}
|
||||
|
||||
if(!profile.getPlayerCount().isEmpty() && !profile.shouldHidePlayers()){
|
||||
ping.setVersionName(ComponentParser.text(profile.getPlayerCount())
|
||||
.replacements(playerPlaceholders)
|
||||
.replacements(serverPlaceholders)
|
||||
.modifyText(text -> {
|
||||
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
|
||||
|
||||
return text;
|
||||
})
|
||||
.toString()
|
||||
);
|
||||
ping.setVersionProtocol(-1);
|
||||
}
|
||||
|
||||
if(!profile.getPlayers().isEmpty() && !profile.shouldHidePlayers()){
|
||||
ping.setPlayers(
|
||||
spigotPlugin.createPlayers(profile.getPlayers(), player.getPlayer(), playerPlaceholders, serverPlaceholders)
|
||||
);
|
||||
}
|
||||
|
||||
if(!profile.getFavicon().isEmpty()){
|
||||
String favName = StringReplacer.replace(profile.getFavicon(), playerPlaceholders.getReplacements());
|
||||
|
||||
WrappedServerPing.CompressedImage favicon = spigotPlugin.getFaviconHandler().getFavicon(favName, image -> {
|
||||
try{
|
||||
return WrappedServerPing.CompressedImage.fromPng(image);
|
||||
}catch(Exception ex){
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
if(favicon == null){
|
||||
spigotPlugin.getPluginLogger().warn("Could not obtain valid Favicon to use.");
|
||||
ping.setFavicon(ping.getFavicon());
|
||||
}else{
|
||||
ping.setFavicon(favicon);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private SpigotPlayer resolvePlayer(InetSocketAddress address, int protocol){
|
||||
String playerName = plugin.getCore().getPlayerHandler().getPlayerByIp(address.getHostString());
|
||||
OfflinePlayer player = Bukkit.getPlayerExact(playerName);
|
||||
|
||||
if(player == null){
|
||||
//noinspection deprecation
|
||||
player = Bukkit.getOfflinePlayer(playerName);
|
||||
|
||||
return new SpigotPlayer(player.hasPlayedBefore() ? player : null, playerName, protocol);
|
||||
}
|
||||
|
||||
return new SpigotPlayer(player, playerName, protocol);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.spigot.logging;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class SpigotLogger implements PluginLogger{
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
public SpigotLogger(Logger logger){
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String msg, Object... args){
|
||||
logger.info(String.format(msg, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Object... args){
|
||||
logger.warning(String.format(msg, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable throwable){
|
||||
logger.log(Level.WARNING, msg, throwable);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
name: 'AdvancedServerList'
|
||||
author: 'Andre_601'
|
||||
version: '${plugin.version}'
|
||||
description: '${plugin.description}'
|
||||
|
||||
main: 'ch.andre601.advancedserverlist.spigot.SpigotCore'
|
||||
|
||||
api-version: 1.19
|
||||
|
||||
libraries:
|
||||
- 'org.spongepowered:configurate-yaml:4.1.2'
|
||||
- 'net.kyori:adventure-api:4.11.0'
|
||||
- 'net.kyori:adventure-text-minimessage:4.11.0'
|
||||
- 'net.kyori:adventure-text-serializer-legacy:4.11.0'
|
||||
- 'net.kyori:adventure-platform-bukkit:4.1.2'
|
||||
|
||||
softdepend:
|
||||
- 'ProtocolLib'
|
||||
- 'PlaceholderAPI'
|
||||
|
||||
commands:
|
||||
advancedserverlist:
|
||||
description: 'Main command of AdvancedServerList'
|
||||
usage: '/<command> [help|reload]'
|
||||
aliases:
|
||||
- 'asl'
|
||||
permission: 'advancedserverlist.admin'
|
||||
|
||||
permissions:
|
||||
advancedserverlist.*:
|
||||
description: 'Grants access to all permissions'
|
||||
default: op
|
||||
children:
|
||||
- 'advancedserverlist.admin'
|
||||
advancedserverlist.admin:
|
||||
description: 'Grants access to all permissions'
|
||||
default: op
|
||||
children:
|
||||
- 'advancedserverlist.command.*'
|
||||
advancedserverlist.command.*:
|
||||
description: 'Grants access to all commands'
|
||||
default: op
|
||||
children:
|
||||
- 'advancedserverlist.command.help'
|
||||
- 'advancedserverlist.command.reload'
|
||||
advancedserverlist.command.help:
|
||||
description: 'Grants access to /asl help'
|
||||
default: op
|
||||
advancedserverlist.command.reload:
|
||||
description: 'Grants access to /asl reload'
|
||||
default: op
|
||||
+43
-2
@@ -1,4 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ MIT License
|
||||
~
|
||||
~ Copyright (c) 2022 Andre_601
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in all
|
||||
~ copies or substantial portions of the Software.
|
||||
~
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
~ SOFTWARE.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
@@ -10,6 +35,8 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>velocity</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>${plugin.version}</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>16</maven.compiler.source>
|
||||
@@ -36,6 +63,12 @@
|
||||
<version>3.1.2-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-velocity</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -55,14 +88,22 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<version>3.4.0</version>
|
||||
<configuration>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.spongepowered.configurate</pattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.velocity.depends.configurate</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.bstats</pattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.velocity.depends.bstats</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.github.benmanes.caffeine</pattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.velocity.depends.caffeine</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<filters>
|
||||
<filter>
|
||||
|
||||
@@ -1,35 +1,75 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.velocity;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.ProxyLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.ProxyCore;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
import ch.andre601.advancedserverlist.velocity.commands.CmdAdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.velocity.events.JoinEvent;
|
||||
import ch.andre601.advancedserverlist.velocity.events.PingEvent;
|
||||
import ch.andre601.advancedserverlist.velocity.logging.VelocityLogger;
|
||||
import com.google.inject.Inject;
|
||||
import com.velocitypowered.api.command.CommandMeta;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
|
||||
import com.velocitypowered.api.plugin.annotation.DataDirectory;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||
import com.velocitypowered.api.util.Favicon;
|
||||
import org.bstats.charts.SimplePie;
|
||||
import org.bstats.velocity.Metrics;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class VelocityCore implements PluginCore{
|
||||
public class VelocityCore implements ProxyCore<Favicon, ServerPing.SamplePlayer>{
|
||||
|
||||
private final ProxyLogger logger;
|
||||
private final PluginLogger logger;
|
||||
private final ProxyServer proxy;
|
||||
private final Path path;
|
||||
private final Metrics.Factory metrics;
|
||||
|
||||
private AdvancedServerList core;
|
||||
private FaviconHandler<Favicon> faviconHandler = null;
|
||||
|
||||
@Inject
|
||||
public VelocityCore(ProxyServer proxy, @DataDirectory Path path){
|
||||
public VelocityCore(ProxyServer proxy, @DataDirectory Path path, Metrics.Factory metrics){
|
||||
this.logger = new VelocityLogger(LoggerFactory.getLogger("AdvancedServerList"));
|
||||
|
||||
this.proxy = proxy;
|
||||
this.path = path;
|
||||
this.metrics = metrics;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -37,6 +77,11 @@ public class VelocityCore implements PluginCore{
|
||||
this.core = new AdvancedServerList(this);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void pluginDisable(ProxyShutdownEvent event){
|
||||
core.disable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCommands(){
|
||||
CommandMeta command = getProxy().getCommandManager()
|
||||
@@ -49,12 +94,23 @@ public class VelocityCore implements PluginCore{
|
||||
|
||||
@Override
|
||||
public void loadEvents(){
|
||||
new JoinEvent(this);
|
||||
new PingEvent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMetrics(){
|
||||
|
||||
metrics.make(this, 15587).addCustomChart(new SimplePie("profiles",
|
||||
() -> String.valueOf(core.getFileHandler().getProfiles().size())
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearFaviconCache(){
|
||||
if(faviconHandler == null)
|
||||
return;
|
||||
|
||||
faviconHandler.clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -63,22 +119,46 @@ public class VelocityCore implements PluginCore{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getPath(){
|
||||
public Path getFolderPath(){
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProxyLogger getProxyLogger(){
|
||||
public PluginLogger getPluginLogger(){
|
||||
return logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProxyName(){
|
||||
public FaviconHandler<Favicon> getFaviconHandler(){
|
||||
if(faviconHandler == null)
|
||||
faviconHandler = new FaviconHandler<>(core);
|
||||
|
||||
return faviconHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServerPing.SamplePlayer> createPlayers(List<String> lines, Placeholders... placeholders){
|
||||
List<ServerPing.SamplePlayer> players = new ArrayList<>(lines.size());
|
||||
|
||||
for(String line : lines){
|
||||
String parsed = ComponentParser.text(line)
|
||||
.replacements(placeholders[0])
|
||||
.replacements(placeholders[1])
|
||||
.toString();
|
||||
|
||||
players.add(new ServerPing.SamplePlayer(parsed, UUID.randomUUID()));
|
||||
}
|
||||
|
||||
return players;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlatformName(){
|
||||
return getProxy().getVersion().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProxyVersion(){
|
||||
public String getPlatformVersion(){
|
||||
return getProxy().getVersion().getVersion();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.velocity;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
|
||||
public class VelocityPlayer extends GenericPlayer<Player>{
|
||||
|
||||
public VelocityPlayer(String name, int protocol){
|
||||
this.name = name;
|
||||
this.protocol = protocol;
|
||||
this.version = ProtocolVersion.getProtocolVersion(protocol).getVersionIntroducedIn();
|
||||
}
|
||||
}
|
||||
+25
@@ -1,3 +1,28 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.velocity.commands;
|
||||
|
||||
import ch.andre601.advancedserverlist.velocity.VelocityCore;
|
||||
|
||||
+26
-1
@@ -1,3 +1,28 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.velocity.commands;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.CmdSender;
|
||||
@@ -19,6 +44,6 @@ public class VelocityCmdSender implements CmdSender{
|
||||
|
||||
@Override
|
||||
public void sendMsg(String msg, Object... args){
|
||||
sender.sendMessage(ComponentParser.toComponent(String.format(msg, args)));
|
||||
sender.sendMessage(ComponentParser.text(String.format(msg, args)).toComponent());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.velocity.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.velocity.VelocityCore;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public class JoinEvent{
|
||||
|
||||
private final VelocityCore plugin;
|
||||
|
||||
public JoinEvent(VelocityCore plugin){
|
||||
this.plugin = plugin;
|
||||
plugin.getProxy().getEventManager().register(plugin, this);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onJoin(PostLoginEvent event){
|
||||
InetSocketAddress address = event.getPlayer().getRemoteAddress();
|
||||
plugin.getCore().getPlayerHandler().addPlayer(event.getPlayer().getUsername(), address.getHostString());
|
||||
}
|
||||
}
|
||||
+95
-12
@@ -1,14 +1,45 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.velocity.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ProfileManager;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.velocity.VelocityCore;
|
||||
import ch.andre601.advancedserverlist.velocity.VelocityPlayer;
|
||||
import com.velocitypowered.api.event.PostOrder;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
|
||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||
import com.velocitypowered.api.util.Favicon;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
public class PingEvent{
|
||||
@@ -28,25 +59,77 @@ public class PingEvent{
|
||||
return;
|
||||
|
||||
ServerPing.Builder builder = ping.asBuilder();
|
||||
ServerListProfile profile = plugin.getCore().getServerListProfile(protocol.getProtocol());
|
||||
String playerName = plugin.getCore().getPlayerHandler().getPlayerByIp(event.getConnection().getRemoteAddress().getHostString());
|
||||
InetSocketAddress host = event.getConnection().getVirtualHost().orElse(null);
|
||||
|
||||
int online = builder.getOnlinePlayers();
|
||||
int max = builder.getMaximumPlayers();
|
||||
|
||||
PlayerPlaceholders playerPlaceholders = new PlayerPlaceholders(new VelocityPlayer(playerName, protocol.getProtocol()));
|
||||
ServerPlaceholders serverPlaceholders = new ServerPlaceholders(online, max, host == null ? null : host.getHostString());
|
||||
|
||||
ServerListProfile profile = ProfileManager.get(plugin.getCore())
|
||||
.replacements(playerPlaceholders)
|
||||
.replacements(serverPlaceholders)
|
||||
.getProfile();
|
||||
|
||||
if(profile == null)
|
||||
return;
|
||||
|
||||
if(profile.isExtraPlayersEnabled()){
|
||||
max = online + profile.getExtraPlayers();
|
||||
builder.maximumPlayers(max);
|
||||
}
|
||||
|
||||
serverPlaceholders = new ServerPlaceholders(online, max, host == null ? null : host.getHostString());
|
||||
|
||||
if(!profile.getMotd().isEmpty()){
|
||||
List<String> motd = profile.getMotd();
|
||||
if(motd.size() > 2)
|
||||
motd = motd.subList(0, 2);
|
||||
|
||||
builder.description(ComponentParser.toComponent(motd));
|
||||
builder.description(ComponentParser.list(motd)
|
||||
.replacements(playerPlaceholders)
|
||||
.replacements(serverPlaceholders)
|
||||
.toComponent()
|
||||
);
|
||||
}
|
||||
|
||||
if(!profile.getPlayerCount().isEmpty()){
|
||||
builder.version(new ServerPing.Version(-1, ComponentParser.toString(profile.getPlayerCount())));
|
||||
if(profile.shouldHidePlayers()){
|
||||
builder.nullPlayers();
|
||||
}
|
||||
|
||||
if(!profile.getPlayers().isEmpty()){
|
||||
ServerPing.SamplePlayer[] players = AdvancedServerList.getPlayers(ServerPing.SamplePlayer.class, profile.getPlayers())
|
||||
if(!profile.getPlayerCount().isEmpty() && !profile.shouldHidePlayers()){
|
||||
builder.version(new ServerPing.Version(
|
||||
-1,
|
||||
ComponentParser.text(profile.getPlayerCount())
|
||||
.replacements(playerPlaceholders)
|
||||
.replacements(serverPlaceholders)
|
||||
.toString()
|
||||
));
|
||||
}
|
||||
|
||||
if(!profile.getPlayers().isEmpty() && !profile.shouldHidePlayers()){
|
||||
ServerPing.SamplePlayer[] playerSamples = plugin.createPlayers(profile.getPlayers(), playerPlaceholders, serverPlaceholders)
|
||||
.toArray(new ServerPing.SamplePlayer[0]);
|
||||
|
||||
if(players.length > 0)
|
||||
builder.clearSamplePlayers().samplePlayers(players);
|
||||
if(playerSamples.length > 0)
|
||||
builder.clearSamplePlayers().samplePlayers(playerSamples);
|
||||
}
|
||||
|
||||
if(!profile.getFavicon().isEmpty()){
|
||||
String favName = StringReplacer.replace(profile.getFavicon(), playerPlaceholders.getReplacements());
|
||||
|
||||
Favicon favicon = plugin.getFaviconHandler().getFavicon(favName, image -> {
|
||||
try{
|
||||
return Favicon.create(image);
|
||||
}catch(Exception ex){
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
if(favicon == null){
|
||||
plugin.getPluginLogger().warn("Could not obtain valid Favicon to use.");
|
||||
}else{
|
||||
builder.favicon(favicon);
|
||||
}
|
||||
}
|
||||
|
||||
event.setPing(builder.build());
|
||||
|
||||
+31
-6
@@ -1,9 +1,34 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.velocity.logging;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.ProxyLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class VelocityLogger implements ProxyLogger{
|
||||
public class VelocityLogger implements PluginLogger{
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
@@ -12,13 +37,13 @@ public class VelocityLogger implements ProxyLogger{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String msg){
|
||||
logger.info(msg);
|
||||
public void info(String msg, Object... args){
|
||||
logger.info(String.format(msg, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg){
|
||||
logger.warn(msg);
|
||||
public void warn(String msg, Object... args){
|
||||
logger.warn(String.format(msg, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in new issue
Block a user