272 lines
9.0 KiB
TypeScript
272 lines
9.0 KiB
TypeScript
|
/// <reference types="@ms/types/dist/typings/bukkit" />
|
||
|
/// <reference types="@ms/types/dist/typings/sponge" />
|
||
|
|
||
|
import { server } from '@ms/api'
|
||
|
import { inject } from '@ms/container';
|
||
|
import { plugin, interfaces, cmd, listener, tab } from '@ms/plugin'
|
||
|
import Tellraw from '@ms/common/dist/tellraw'
|
||
|
|
||
|
@plugin({ name: 'MiaoChat', version: '1.0.0', author: 'MiaoWoo', source: __filename })
|
||
|
export class MiaoChat extends interfaces.Plugin {
|
||
|
@inject(server.Server)
|
||
|
private Server: server.Server
|
||
|
|
||
|
private config = {
|
||
|
Version: "1.8.5",
|
||
|
BungeeCord: true,
|
||
|
Server: "生存服",
|
||
|
ChatFormats: {
|
||
|
default: {
|
||
|
index: 50,
|
||
|
permission: "MiaoChat.default",
|
||
|
range: 0,
|
||
|
format: "[world][player]: ",
|
||
|
item: true,
|
||
|
itemformat: "&6[&b%s&6]&r"
|
||
|
},
|
||
|
admin: {
|
||
|
index: 49,
|
||
|
permission: "MiaoChat.admin",
|
||
|
format: "[admin][world][player][help]: ",
|
||
|
range: 0,
|
||
|
item: true,
|
||
|
itemformat: "&6[&b%s&6]&r"
|
||
|
}
|
||
|
},
|
||
|
StyleFormats: {
|
||
|
world: {
|
||
|
text: "&6[&a%player_world%&6]",
|
||
|
hover: [
|
||
|
"&6当前所在位置:",
|
||
|
"&6世界: &d%player_world%",
|
||
|
"&6坐标: &aX:%player_x% Y: %player_y% Z: %player_z%",
|
||
|
"",
|
||
|
"&c点击即可TP我!"
|
||
|
],
|
||
|
click: {
|
||
|
type: "COMMAND",
|
||
|
command: "/tpa %player_name%"
|
||
|
}
|
||
|
},
|
||
|
player: {
|
||
|
text: "&b%player_name%",
|
||
|
hover: [
|
||
|
"&6玩家名称: &b%player_name%",
|
||
|
"&6玩家等级: &a%player_level%",
|
||
|
"&6玩家血量: &c%player_health%",
|
||
|
"&6玩家饥饿: &d%player_food_level%",
|
||
|
"&6游戏模式: &4%player_gamemode%",
|
||
|
"",
|
||
|
"&c点击与我聊天"
|
||
|
],
|
||
|
click: {
|
||
|
type: "SUGGEST",
|
||
|
command: "/tell %player_name%"
|
||
|
}
|
||
|
},
|
||
|
admin: {
|
||
|
text: "&6[&c管理员&6]"
|
||
|
},
|
||
|
help: {
|
||
|
text: "&4[求助]",
|
||
|
hover: [
|
||
|
"点击求助OP"
|
||
|
],
|
||
|
click: {
|
||
|
type: "COMMAND",
|
||
|
command: "管理员@%player_name% 我需要你的帮助!"
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private chatFormats: any[];
|
||
|
private styleFormats: any;
|
||
|
// 用于匹配 '[xx]' 聊天格式
|
||
|
private FORMAT_PATTERN = /[\[]([^\[\]]+)[\]]/ig;
|
||
|
|
||
|
private PlaceholderAPI: { setPlaceholders: (player: any, str: string) => string };
|
||
|
|
||
|
load() {
|
||
|
if (!Object.values) {
|
||
|
Object.defineProperty(Object, "values", {
|
||
|
enumerable: false,
|
||
|
configurable: true,
|
||
|
writable: true,
|
||
|
value: function(target) {
|
||
|
"use strict";
|
||
|
var values = [];
|
||
|
for (var key in target) {
|
||
|
var desc = Object.getOwnPropertyDescriptor(target, key);
|
||
|
if (desc !== undefined && desc.enumerable) values.push(target[key]);
|
||
|
}
|
||
|
return values;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
this.chatFormats = Object.values(this.config.ChatFormats);
|
||
|
this.chatFormats.sort(this.compare('index'));
|
||
|
this.initFormat(this.chatFormats);
|
||
|
this.styleFormats = this.config.StyleFormats;
|
||
|
}
|
||
|
|
||
|
private compare(prop: string) {
|
||
|
return function(obj1: { [x: string]: any; }, obj2: { [x: string]: any; }) {
|
||
|
var val1 = obj1[prop];
|
||
|
var val2 = obj2[prop];
|
||
|
if (!isNaN(Number(val1)) && !isNaN(Number(val2))) {
|
||
|
val1 = Number(val1);
|
||
|
val2 = Number(val2);
|
||
|
}
|
||
|
if (val1 < val2) {
|
||
|
return -1;
|
||
|
} else if (val1 > val2) {
|
||
|
return 1;
|
||
|
} else {
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
enable() {
|
||
|
}
|
||
|
disable() {
|
||
|
}
|
||
|
|
||
|
bukkitenable() {
|
||
|
// 尝试加载 Bukkit 的 PlaceholderAPI
|
||
|
try {
|
||
|
//@ts-ignore
|
||
|
this.PlaceholderAPI = base.getClass("me.clip.placeholderapi.PlaceholderAPI").static;
|
||
|
console.log('[PAPI] Found Bukkit PlaceholderAPI Hooking...')
|
||
|
} catch (ex) {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
spongeenable() {
|
||
|
// 尝试加载 Sponge 的 PlaceholderAPI
|
||
|
try {
|
||
|
var spongePapi = this.Server.getService('me.rojo8399.placeholderapi.PlaceholderService');
|
||
|
var s = org.spongepowered.api.text.serializer.TextSerializers.formattingCode('§');
|
||
|
if (spongePapi) {
|
||
|
this.PlaceholderAPI = {
|
||
|
setPlaceholders: (player: any, string: string) => {
|
||
|
return s.serialize(spongePapi.replacePlaceholders(string, player, player));
|
||
|
}
|
||
|
};
|
||
|
console.log('[PAPI] Found Sponge PlaceholderAPI Hooking...')
|
||
|
}
|
||
|
} catch (ex) {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@cmd()
|
||
|
mchat(sender: any, command: string, args: string[]) {
|
||
|
this.logger.log(sender, command, args);
|
||
|
sender.sendMessage(JSON.stringify({ command, ...args }))
|
||
|
}
|
||
|
|
||
|
@tab()
|
||
|
tabmchat(_sender: any, _command: string, _args: string[]) {
|
||
|
}
|
||
|
|
||
|
@listener({ servertype: 'bukkit' })
|
||
|
AsyncPlayerChatEvent(event: org.bukkit.event.player.AsyncPlayerChatEvent) {
|
||
|
this.sendChat(event.getPlayer(), event.getMessage(), function() {
|
||
|
event.setCancelled(true);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
@listener({ servertype: 'sponge' })
|
||
|
MessageChannelEvent$Chat(event: org.spongepowered.api.event.message.MessageChannelEvent.Chat) {
|
||
|
//@ts-ignore
|
||
|
var player = event.getCause().first(org.spongepowered.api.entity.living.player.Player.class).orElse(null);
|
||
|
if (player == null) {
|
||
|
return;
|
||
|
}
|
||
|
var plain = event.getRawMessage().toPlain();
|
||
|
if (plain.startsWith(Tellraw.duplicateChar)) {
|
||
|
return;
|
||
|
}
|
||
|
this.sendChat(player, plain, function() {
|
||
|
event.setMessageCancelled(true)
|
||
|
});
|
||
|
}
|
||
|
|
||
|
initFormat(chatFormats: any[]) {
|
||
|
chatFormats.forEach(chatFormat => {
|
||
|
var chat_format_str = chatFormat.format;
|
||
|
var temp = [];
|
||
|
var r: any[];
|
||
|
while (r = this.FORMAT_PATTERN.exec(chat_format_str)) {
|
||
|
temp.push(r[1]);
|
||
|
}
|
||
|
var format_list = [];
|
||
|
temp.forEach(function splitStyle(t) {
|
||
|
var arr = chat_format_str.split('[' + t + ']', 2);
|
||
|
if (arr[0]) {
|
||
|
format_list.push(arr[0]);
|
||
|
}
|
||
|
format_list.push(t);
|
||
|
chat_format_str = arr[1];
|
||
|
});
|
||
|
if (chat_format_str) {
|
||
|
format_list.push(chat_format_str);
|
||
|
}
|
||
|
chatFormat.format_list = format_list;
|
||
|
})
|
||
|
}
|
||
|
|
||
|
sendChat(player: any, plain: string, callback: { (): void; }) {
|
||
|
var chat_format = this.getChatFormat(player);
|
||
|
if (!chat_format) {
|
||
|
console.debug('未获得用户', player.getName(), '的 ChatRule 跳过执行...');
|
||
|
return;
|
||
|
}
|
||
|
callback();
|
||
|
var tr = Tellraw.create();
|
||
|
chat_format.format_list.forEach((format) => {
|
||
|
var style = this.styleFormats[format];
|
||
|
if (style) {
|
||
|
tr.then(this.replace(player, style.text));
|
||
|
if (style.hover) {
|
||
|
tr.tip(this.replace(player, style.hover.join('\n')));
|
||
|
}
|
||
|
if (style.click && style.click.type && style.click.command) {
|
||
|
var command = this.replace(player, style.click.command);
|
||
|
switch (style.click.type.toUpperCase()) {
|
||
|
case "COMMAND":
|
||
|
tr.command(command);
|
||
|
break;
|
||
|
case "OPENURL":
|
||
|
tr.link(command);
|
||
|
break;
|
||
|
case "SUGGEST":
|
||
|
tr.suggest(command);
|
||
|
break;
|
||
|
default:
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
tr.then(this.replace(player, format));
|
||
|
}
|
||
|
});
|
||
|
let json = tr.then(this.replace(player, plain)).json()
|
||
|
this.Server.getOnlinePlayers().forEach(player => this.Server.sendJson(player, json))
|
||
|
}
|
||
|
|
||
|
getChatFormat(player: any) {
|
||
|
for (var i in this.chatFormats) {
|
||
|
var format = this.chatFormats[i];
|
||
|
if (player.hasPermission(format.permission)) {
|
||
|
return format;
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
replace(player: any, target: string) {
|
||
|
return this.PlaceholderAPI.setPlaceholders(player, target)
|
||
|
}
|
||
|
}
|