Skip to content

Commit

Permalink
add support for XBOX Live players (proxied by Geyser) by automaticall…
Browse files Browse the repository at this point in the history
…y converting XBOX Live GamerTag to UUID

minor refactoring
minor improvement on error handling
update version code to v2.3
resolve #5
  • Loading branch information
Luluno01 committed Sep 21, 2020
1 parent 4a16637 commit dbebfd4
Show file tree
Hide file tree
Showing 10 changed files with 289 additions and 34 deletions.
51 changes: 49 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ Tested on Waterfall, version: `git:Waterfall-Bootstrap:1.16-R0.4-SNAPSHOT:8afc4e
- [Features](#features)
- [Usage](#usage)
- [Migrate to v2.0](#migrate-to-v20)
- [XBOX Live Player Support (Bedrock Edition Support)](#xbox-live-player-support-bedrock-edition-support)
- [Configuration](#configuration)
- [Commands](#commands)
- [Whitelist](#whitelist)
- [whitelist add](#whitelist-add)
- [whitelist x-add](#whitelist-x-add)
- [whitelist lazy-add](#whitelist-lazy-add)
- [whitelist remove](#whitelist-remove)
- [whitelist x-remove](#whitelist-x-remove)
- [whitelist lazy-remove](#whitelist-lazy-remove)
- [whitelist on](#whitelist-on)
- [whitelist off](#whitelist-off)
Expand All @@ -38,6 +41,7 @@ Tested on Waterfall, version: `git:Waterfall-Bootstrap:1.16-R0.4-SNAPSHOT:8afc4e

* First **UUID-based** blacklist and whitelist plugin for BungeeCord
* Add and remove players by their **username** or UUID (username-change-proof)
* Add and remove XBOX Live players by their **Gamer Tag** or UUID (Gamertag-change-proof) (from v2.3, see [XBOX Live Player Support](#xbox-live-player-support-bedrock-edition-support) for more details)
* Lazy translation from username to UUID (from v1.2, **offline server friendly**, see [lazy lists](#lazy-lists) for details)

## Usage
Expand All @@ -63,19 +67,27 @@ To migrate to v2.0 from lower versions, do the following:

You are now good to go.

## XBOX Live Player Support (Bedrock Edition Support)

Since version `v2.3`, BungeeSafeguard now supports automatic conversion from XBOX Live Gamer Tag to Minecraft-compatible UUID following the conversion rule as defined by [Geyser](https://geysermc.org/). This new feature hopefully resolves the issue #5.
XBOX Live Gamer Tags are now added via the command [`x-add`](#whitelist-x-add) and removed via the command [`x-rm`](#whitelist-x-remove).
There is no need to implement lazy lists for XBOX Live players because current lazy lists are compatible with XBOX Live players.

Note that you need to specify an [`xbl-web-api`](https://github.com/Prouser123/xbl-web-api) instance (you can either deploy your own or use the public one provided by [`xbl-web-api`](https://xbl-api.prouser123.me/)) by setting its URL as the value of the configuration entry `xbl-web-api` (see section [Configuration](#configuration)).

## Configuration

The configuration file for BungeeSafeguard is `plugins/BungeeSafeguard/config.yml`.

```yaml
#########################################
# BungeeSafeguard Configuration #
# Version: 2.2 #
# Version: 2.3 #
# Author: Untitled #
#########################################

# You can safely ignore this
version: "2.2"
version: "2.3"

# Message to be sent to the player when that player is blocked for not being whitelisted
whitelist-message: :( You are not whitelisted on this server
Expand Down Expand Up @@ -111,6 +123,9 @@ lazy-blacklist:
# blacklist:
# - <banned UUID>
blacklist:

# xbl-web-api: <a deployment of https://github.com/Prouser123/xbl-web-api>
xbl-web-api: https://xbl-api.prouser123.me
```
Note that if you enable both blacklist and whitelist (which is weird, but it is possible to do that), player in both lists will be blocked because blacklist has a higher priority over whitelist.
Expand All @@ -135,6 +150,22 @@ Example:
whitelist add DummyPlayer0 DummyPlayer1 7be767e5-327c-4abd-852b-afab3ec1e2ff DummyPlayer2
```

#### whitelist x-add

Alias: `xadd`.

Add XBOX Live player(s) to whitelist:

```
whitelist x-add <space separated GamerTags or converted UUIDs>
```

Example:

```
whitelist x-add DummyPlayer0 DummyPlayer1 00000000-0000-0000-852b-afab3ec1e2ff DummyPlayer2
```

#### whitelist lazy-add

Alias: `whitelist lazyadd` or `whitelist ladd`.
Expand Down Expand Up @@ -167,6 +198,22 @@ Example:
whitelist remove DummyPlayer0 DummyPlayer1 7be767e5-327c-4abd-852b-afab3ec1e2ff DummyPlayer2
```

#### whitelist x-remove

Alias: `whitelist xremove`, `whitelist x-rm` or `whitelist xrm`.

Remove XBOX Live player(s) from whitelist:

```
whitelist x-remove <space separated GamerTags or converted UUIDs>
```

Example:

```
whitelist x-remove DummyPlayer0 DummyPlayer1 00000000-0000-0000-852b-afab3ec1e2ff DummyPlayer2
```

#### whitelist lazy-remove

Alias: `whitelist lazyremove`, `whitelist lremove` or `whitelist lrm`.
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

group 'vip.untitled'
version '2.0-SNAPSHOT'
version '2.3-SNAPSHOT'

sourceCompatibility = 1.8

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ open class BungeeSafeguard: ConfigHolderPlugin() {
logger.warning("======== Start dumping blacklist enable state for data recovery ========")
logger.warning(config.enableBlacklist.toString())
logger.warning("======== End dumping blacklist enable state for data recovery ========")
logger.warning("======== Start dumping XBL Web API URL for data recovery ========")
logger.warning(config.xblWebAPIUrl)
logger.warning("======== End dumping XBL Web API URL for data recovery ========")
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/main/kotlin/vip/untitled/bungeesafeguard/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ open class Config(val context: Plugin) {
const val NO_UUID_MESSAGE = "no-uuid-message"
const val ENABLED_WHITELIST = "enable-whitelist"
const val ENABLED_BLACKLIST = "enable-blacklist"
const val XBL_WEB_API = "xbl-web-api"
}
@Volatile
open lateinit var conf: Configuration
Expand Down Expand Up @@ -60,6 +61,8 @@ open class Config(val context: Plugin) {
open var enableWhitelist = true
@Volatile
open var enableBlacklist = false
@Volatile
open var xblWebAPIUrl: String? = null
protected open val dataFolder: File
get() = context.dataFolder
protected open val logger: Logger
Expand Down Expand Up @@ -104,6 +107,7 @@ open class Config(val context: Plugin) {
if (enableWhitelist) logger.warning("Both blacklist and whitelist are enabled, blacklist will have a higher priority should a player is in both list")
else logger.warning("Both blacklist and whitelist are disabled, BungeeSafeguard will not block any player")
}
xblWebAPIUrl = if (conf.contains(XBL_WEB_API)) conf.getString(XBL_WEB_API) else null
}

open fun loadConfigFromFile(): Configuration {
Expand Down
73 changes: 62 additions & 11 deletions src/main/kotlin/vip/untitled/bungeesafeguard/commands/Blacklist.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ import java.util.*
open class Blacklist(context: ConfigHolderPlugin): ListCommand(context, "blacklist", "bungeesafeguard.blacklist", "blist") {
override fun sendUsage(sender: CommandSender) {
sender.sendMessage(TextComponent("${ChatColor.YELLOW}Usage:"))
sender.sendMessage(TextComponent("${ChatColor.YELLOW} /blacklist <add/remove/rm> <player ...>"))
sender.sendMessage(TextComponent("${ChatColor.YELLOW}Or:"))
sender.sendMessage(TextComponent("${ChatColor.YELLOW} /blacklist <lazy-add/lazy-remove/lazyadd/ladd/lazyremove/lremove/lrm> <player ...>"))
sender.sendMessage(TextComponent("${ChatColor.YELLOW}Or:"))
sender.sendMessage(TextComponent("${ChatColor.YELLOW} For normal Mojang players: /blacklist <add/remove/rm> <player ...>"))
sender.sendMessage(TextComponent("${ChatColor.YELLOW} For XBOX Live players: /blacklist <x-add/xadd/x-remove/x-remove/x-rm/xrm> <player ...>"))
sender.sendMessage(TextComponent("${ChatColor.YELLOW} For both Mojang and XBOX players: /blacklist <lazy-add/lazy-remove/lazyadd/ladd/lazyremove/lremove/lrm> <player ...>"))
sender.sendMessage(TextComponent("${ChatColor.YELLOW} /blacklist <on/off>"))
}

Expand All @@ -24,22 +23,36 @@ open class Blacklist(context: ConfigHolderPlugin): ListCommand(context, "blackli
* @param args Array of UUID(s) or username(s) (can be a mixed array)
*/
override fun addAsync(sender: CommandSender, args: Array<out String>) {
addAsync(sender, args, false)
}

/**
* Add UUID(s) converted from XUID(s) or XBOX Gamertag(s) to blacklist asynchronously
* @param sender Command sender
* @param args Array of UUID(s) or username(s) (can be a mixed array)
*/
override fun xAddAsync(sender: CommandSender, args: Array<out String>) {
addAsync(sender, args, true)
}

protected fun addAsync(sender: CommandSender, args: Array<out String>, xbox: Boolean) {
var lastSyncError: Throwable? = null
val concurrentTasksHelper = getConcurrentTasksHelperForConfigSaving(args.size)
for (usernameOrUUID in args) {
UserUUIDHelper.getUUIDFromString(context, usernameOrUUID) { err, uuid ->
val onUUID = { err: Throwable?, uuid: UUID? ->
try {
when (err) {
null -> {
assert(uuid != null) { "Both error and UUID are null!" }
synchronized(config) {
if (config.inWhitelist(uuid!!)) {
sender.sendMessage(TextComponent("${ChatColor.YELLOW}${usernameOrUUID} is already whitelisted, whose priority is lower than blacklist"))
sender.sendMessage(TextComponent("${ChatColor.YELLOW}${usernameOrUUID} ${ChatColor.AQUA}($uuid) ${ChatColor.YELLOW}is already whitelisted, whose priority is lower than blacklist"))
}
if (config.inBlacklist(uuid)) {
sender.sendMessage(TextComponent("${ChatColor.YELLOW}${usernameOrUUID} is already blacklisted"))
sender.sendMessage(TextComponent("${ChatColor.YELLOW}${usernameOrUUID} ${ChatColor.AQUA}($uuid) ${ChatColor.YELLOW}is already blacklisted"))
} else {
config.addBlacklistRecord(uuid)
sender.sendMessage(TextComponent("${ChatColor.AQUA}${usernameOrUUID} added to blacklist"))
sender.sendMessage(TextComponent("${ChatColor.AQUA}${usernameOrUUID} ${ChatColor.YELLOW}($uuid) ${ChatColor.AQUA}added to blacklist"))
synchronized (concurrentTasksHelper) {
concurrentTasksHelper.shouldSaveConfig = true
}
Expand All @@ -57,6 +70,18 @@ open class Blacklist(context: ConfigHolderPlugin): ListCommand(context, "blackli
concurrentTasksHelper.notifyCompletion()
}
}
try {
if (xbox) UserUUIDHelper.getUUIDFromXBOXTag(context, usernameOrUUID, onUUID)
else UserUUIDHelper.getUUIDFromString(context, usernameOrUUID, onUUID)
} catch (e: Throwable) {
lastSyncError = e
concurrentTasksHelper.notifyCompletion()
}
}
if (lastSyncError != null) {
sender.sendMessage(TextComponent("${ChatColor.YELLOW}Some error occurred, check the console for more details"))
context.logger.warning("Last error:")
lastSyncError.printStackTrace()
}
}

Expand All @@ -66,20 +91,34 @@ open class Blacklist(context: ConfigHolderPlugin): ListCommand(context, "blackli
* @param args Array of UUID(s) or username(s) (can be a mixed array)
*/
override fun removeAsync(sender: CommandSender, args: Array<out String>) {
removeAsync(sender, args, false)
}

/**
* Remove UUID(s) converted from XUID(s) or XBOX Gamertag(s) from blacklist asynchronously
* @param sender Command sender
* @param args Array of UUID(s) converted from XUID(s) or XBOX Gamertag(s) (can be a mixed array)
*/
override fun xRemoveAsync(sender: CommandSender, args: Array<out String>) {
removeAsync(sender, args, true)
}

protected fun removeAsync(sender: CommandSender, args: Array<out String>, xbox: Boolean) {
var lastSyncError: Throwable? = null
val concurrentTasksHelper = getConcurrentTasksHelperForConfigSaving(args.size)
for (usernameOrUUID in args) {
UserUUIDHelper.getUUIDFromString(context, usernameOrUUID) { err, uuid ->
val onUUID = { err: Throwable?, uuid: UUID? ->
try {
when (err) {
null -> {
assert(uuid != null) { "Both error and UUID are null!" }
synchronized (config) {
if (config.inBlacklist(uuid!!)) {
config.removeBlacklistRecord(uuid)
sender.sendMessage(TextComponent("${ChatColor.YELLOW}${usernameOrUUID} removed from blacklist"))
sender.sendMessage(TextComponent("${ChatColor.YELLOW}${usernameOrUUID} ${ChatColor.AQUA}($uuid) ${ChatColor.YELLOW}removed from blacklist"))
concurrentTasksHelper.shouldSaveConfig = true
} else {
sender.sendMessage(TextComponent("${ChatColor.YELLOW}${usernameOrUUID} is not in blacklist"))
sender.sendMessage(TextComponent("${ChatColor.YELLOW}${usernameOrUUID} ${ChatColor.AQUA}($uuid) ${ChatColor.YELLOW}is not in blacklist"))
}
}
}
Expand All @@ -94,6 +133,18 @@ open class Blacklist(context: ConfigHolderPlugin): ListCommand(context, "blackli
concurrentTasksHelper.notifyCompletion()
}
}
try {
if (xbox) UserUUIDHelper.getUUIDFromXBOXTag(context, usernameOrUUID, onUUID)
else UserUUIDHelper.getUUIDFromString(context, usernameOrUUID, onUUID)
} catch (e: Throwable) {
lastSyncError = e
concurrentTasksHelper.notifyCompletion()
}
}
if (lastSyncError != null) {
sender.sendMessage(TextComponent("${ChatColor.YELLOW}Some error occurred, check the console for more details"))
context.logger.warning("Last error:")
lastSyncError.printStackTrace()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ abstract class ListCommand(val context: ConfigHolderPlugin, name: String, permis
*/
abstract fun addAsync(sender: CommandSender, args: Array<out String>)

/**
* Add UUID(s) converted from XUID(s) or XBOX Gamertag(s) to the list asynchronously
* @param sender Command sender
* @param args Array of UUID(s) or username(s) (can be a mixed array)
*/
abstract fun xAddAsync(sender: CommandSender, args: Array<out String>)

/**
* Lazy-add UUID(s) or username(s) to the list synchronously
* @param sender Command sender
Expand All @@ -42,6 +49,13 @@ abstract class ListCommand(val context: ConfigHolderPlugin, name: String, permis
*/
abstract fun removeAsync(sender: CommandSender, args: Array<out String>)

/**
* Remove UUID(s) converted from XUID(s) or XBOX Gamertag(s) from the list asynchronously
* @param sender Command sender
* @param args Array of UUID(s) converted from XUID(s) or XBOX Gamertag(s) (can be a mixed array)
*/
abstract fun xRemoveAsync(sender: CommandSender, args: Array<out String>)

/**
* Lazy-remove UUID(s) or username(s) from the list synchronously
* @param sender Command sender
Expand Down Expand Up @@ -85,6 +99,13 @@ abstract class ListCommand(val context: ConfigHolderPlugin, name: String, permis
sendUsage(sender)
}
}
"x-add", "xadd" -> {
if (args.size > 1) {
xAddAsync(sender, args.copyOfRange(1, args.size))
} else {
sendUsage(sender)
}
}
"lazy-add", "lazyadd", "ladd" -> {
if (args.size > 1) {
lazyAdd(sender, args.copyOfRange(1, args.size))
Expand All @@ -99,6 +120,14 @@ abstract class ListCommand(val context: ConfigHolderPlugin, name: String, permis
sendUsage(sender)
}
}
"x-rm", "xrm",
"x-remove", "xremove" -> {
if (args.size > 1) {
xRemoveAsync(sender, args.copyOfRange(1, args.size))
} else {
sendUsage(sender)
}
}
"lazy-remove", "lazyremove", "lremove", "lrm" -> {
if (args.size > 1) {
lazyRemove(sender, args.copyOfRange(1, args.size))
Expand Down
Loading

0 comments on commit dbebfd4

Please sign in to comment.