Skip to content

Commit

Permalink
Merge pull request #2 from skuzow/feature/helper
Browse files Browse the repository at this point in the history
feat: plugin basis & offline whitelist add command & lots of utilities
  • Loading branch information
skuzow authored Jun 26, 2022
2 parents afb4a92 + ca877d7 commit c3d7ccd
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 1 deletion.
1 change: 0 additions & 1 deletion offline-whitelist/__init__.py

This file was deleted.

31 changes: 31 additions & 0 deletions offline_whitelist/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from mcdreforged.api.all import *
from offline_whitelist.commands import whitelist_add
from offline_whitelist.utils import load_config

PLUGIN_METADATA = ServerInterface.get_instance().as_plugin_server_interface().get_self_metadata()


prefix = '!!offw'
description = PLUGIN_METADATA.description
help_message = '''
--- MCDR {1} v{2} ---
- {3} plugin
{0} add §6[username] §rAdd offline player to whitelist
'''.strip().format(prefix, PLUGIN_METADATA.name, PLUGIN_METADATA.version, description)


def on_load(server: PluginServerInterface, old):
load_config(None, server)
server.register_help_message(prefix, description)
register_commands(server)


def register_commands(server: PluginServerInterface):
def get_username(callback):
return Text('username').runs(callback)
server.register_command(
Literal(prefix).
runs(lambda src: src.reply(help_message)).
on_error(UnknownArgument, lambda src: src.reply(f'Parameter error! Please enter §7{prefix}§r to get plugin help'), handled=True).
then(Literal('add').then(get_username(lambda src, ctx: whitelist_add(src, ctx['username']))))
)
28 changes: 28 additions & 0 deletions offline_whitelist/commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import time

from mcdreforged.api.all import *
from offline_whitelist.utils import get_config, find_file, generate_offline, load_file, dump_file, send_info, \
send_error, check_permission


def whitelist_add(source: CommandSource, username):
config = get_config()
if find_file(source, config.whitelist_path) and check_permission(source, 3):
source.get_server().execute(f'whitelist add {username}')
time.sleep(0.5)
offline_uuid = generate_offline(source, username)
whitelist_json = load_file(source, config.whitelist_path)
# search player username inside whitelist & change uuid to offline one
for player in whitelist_json:
if player["name"] == username:
if not player["uuid"] == offline_uuid:
player["uuid"] = offline_uuid
dump_file(source, config.whitelist_path, whitelist_json)
source.get_server().execute('whitelist reload')
return send_info(source, f'Successfully added to whitelist: {username}')
else:
return send_error(source, f'Player already whitelisted: {username}', None)
# couldn't find nickname because bad written / only for online players
send_error(source, f'Username is misspelled: {username}', None)
source.get_server().execute(f'whitelist remove {username}')
source.get_server().execute('whitelist reload')
93 changes: 93 additions & 0 deletions offline_whitelist/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import hashlib
import json
import os
from typing import Optional

from mcdreforged.api.all import *

PLUGIN_METADATA = ServerInterface.get_instance().as_plugin_server_interface().get_self_metadata()


class Config(Serializable):
whitelist_path: str = './server/whitelist.json'


config: Optional[Config] = None


def generate_offline(source: CommandSource, username):
# extracted from the java code:
# new GameProfile(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)), name));
string = "OfflinePlayer:" + username
hash = hashlib.md5(string.encode('utf-8')).digest()
byte_array = [byte for byte in hash]
byte_array[6] = hash[6] & 0x0f | 0x30
byte_array[8] = hash[8] & 0x3f | 0x80
offline_uuid = __add_stripes(bytes(byte_array).hex())
source.get_server().logger.info(f'Username converted: {username} -> uuid: {offline_uuid}')
return offline_uuid


def __add_stripes(uuid):
return uuid[:8] + '-' + uuid[8:12] + '-' + uuid[12:16] + '-' + uuid[16:20] + '-' + uuid[20:]


def check_permission(source: CommandSource, min_permission_level):
if source.has_permission_higher_than(min_permission_level - 1):
return True
else:
source.reply('You don\'t permission to run this command')
return False


def load_config(source: Optional[CommandSource], server: PluginServerInterface):
global config
config_file_path = os.path.join('config', '{}.json'.format(PLUGIN_METADATA.id))
config = server.load_config_simple(config_file_path, in_data_folder=False, source_to_reply=source,
echo_in_console=False, target_class=Config)


def get_config():
return config


def send_info(source: CommandSource, message):
source.reply(message)
source.get_server().logger.info(message)


def send_error(source: CommandSource, message, error):
source.reply(message)
source.get_server().logger.error(message)
if error is not None:
source.get_server().logger.error(error)


def find_file(source: CommandSource, file_path):
# check if file with path given exists
if os.path.isfile(file_path):
return True
send_error(source, f'Couldn\'t found file: {config.whitelist_path}', None)
return False


def load_file(source: CommandSource, file_path):
try:
# open, load & close file in read mode
read_file = open(file_path, 'r')
file_json = json.load(read_file)
read_file.close()
return file_json
except Exception as error:
send_error(source, f'Couldn\'t load file: {file_path}', error)


def dump_file(source: CommandSource, file_path, file_json):
try:
# open file in write mode
write_file = open(file_path, 'w')
# save changes into the file in the disk, then closes it
json.dump(file_json, write_file, indent=2)
source.get_server().execute('whitelist reload')
except Exception as error:
send_error(source, f'Couldn\'t dump file: {file_path}', error)

0 comments on commit c3d7ccd

Please sign in to comment.