ms/packages/plugins/src/MiaoChat.ts

272 lines
9.0 KiB
TypeScript
Raw Normal View History

/// <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)
}
}