271
packages/plugins/src/MiaoChat.ts
Normal file
271
packages/plugins/src/MiaoChat.ts
Normal file
@@ -0,0 +1,271 @@
|
||||
/// <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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user