Skip to content

Commit

Permalink
1.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ljm12914 committed Oct 5, 2024
1 parent cca35a2 commit 7e04cfd
Show file tree
Hide file tree
Showing 29 changed files with 2,371 additions and 874 deletions.
14 changes: 9 additions & 5 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
"header": {
"name": "自定义命令",
"description": "基岩之上服务器模组。提供服务器所有的命令功能。",
"min_engine_version": [ 1, 21, 20 ],
"min_engine_version": [ 1, 21, 30 ],
"uuid": "03bdd0ea-7bfe-4645-8622-e6b984d79f6e",
"version": [ 1, 1, 0 ]
"version": [ 1, 2, 0 ]
},
"modules": [
{
Expand All @@ -21,17 +21,21 @@
"uuid": "9ccb122c-f901-4e37-8d23-aa3d6e7ea22c",
"version": [ 1, 0, 0 ],
"language": "javascript",
"entry": "scripts/main.js"
"entry": "scripts/index.js"
}
],
"dependencies": [
{
"module_name": "@minecraft/server",
"version": "1.14.0-beta"
"version": "1.15.0-beta"
},
{
"module_name": "@minecraft/server-ui",
"version": "1.3.0-beta"
"version": "1.4.0-beta"
},
{
"module_name": "@minecraft/server-net",
"version": "1.0.0-beta"
}
]
}
29 changes: 10 additions & 19 deletions scripts/about.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//@ts-check
import { system } from "@minecraft/server";
import { registerCommand } from "./commandBase";
import { randomInt } from "./utils/random";
import { absPlayerNames, meta } from "./common";

export function aboutInit(){}

Expand All @@ -11,25 +11,16 @@ registerCommand({
document: "LJM12914荣誉出品。",
args: [],
callback: (_name, player)=>{
player.sendMessage(`§e§l基岩之上服务器`);
player.sendMessage("§。§e§lAboveBedrock SMP");
player.sendMessage("第八季");
player.sendMessage("§b版本:1.21.20/21");
player.sendMessage(`白名单玩家:${[
"LJM12914",
"DK6666Orange",
"TJJ456",
"gaobaisixi",
"Cyttong0222",
"wjlfish",
"Lyzyx99",
"Cr3st_39"
].join(", ")}`);
player.sendMessage("§b网站:https://www.abovebedrock.com");
player.sendMessage("§6IP地址:abovebedrock.com(19132)");
player.sendMessage(`§e§l基岩之上服务器第${meta.season}季`);
player.sendMessage(`§。§e§lAboveBedrock SMP Season ${meta.seasonNum}`);
player.sendMessage(`§b当前版本: ${meta.version} 更新时间: ${meta.updateTime}`);
player.sendMessage(`白名单玩家: ${absPlayerNames.join(", ")}`);
player.sendMessage("§b网站: https://www.abovebedrock.com");
player.sendMessage("§bQQ群: 811530587");
player.sendMessage("§6IP: abovebedrock.com");
player.sendMessage("§。§e§l2018-2024 ABS!");
system.run(()=>player.dimension.playSound(`horn.call.${randomInt(0, 7)}`, player.location, {
volume: 1.0,
system.run(()=>player.playSound(`horn.call.${randomInt(0, 7)}`, {
volume: 0.9,
pitch: 1.0
}));
return true;
Expand Down
127 changes: 106 additions & 21 deletions scripts/antiCheat/ban.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,98 @@
//@ts-check
import { Player, system, world } from "@minecraft/server";
import { Player, system, world } from "@minecraft/server";
import { registerCommand } from "../commandBase";

export function banInit(){}

const unbanList = [
""
];

console.warn(`Unban list: ${unbanList.join(", ")}`);

registerCommand({
names: ["ban"],
description: "封禁或解禁玩家。持续时间以秒计。",
args: [
{
name: "playerOrList",
optional: false,
type: "string"
},
{
name: "isUnban",
optional: true,
type: "boolean"
},
{
name: "duration",
optional: true,
type: "number"
}
],
tagsRequired: ["dev"],
callback: (_names, player, args)=>{
if(args.playerOrList === "list"){
const wps = world.getDynamicPropertyIds(), results = ["名称: 天,小时,分钟,秒"];
for(let i = 0; i < wps.length; i++) if(wps[i].startsWith("b#", 0)) results.push(`${wps[i].substring(2, wps[i].length)}${getRestDuration(Math.floor((parseInt(/**@type {string}*/ (world.getDynamicProperty(wps[i])).split("#")[0]) - system.currentTick) / 20)).join(",")}`);
player.sendMessage(results.length === 1 ? "无封禁玩家。" : results.join("\n"));
}
else{
const banData = world.getDynamicProperty(`b#${args.playerOrList}`);
if(args.isUnban === true){
if(banData !== undefined){
unban(/**@type {string}*/ (args.playerOrList));
player.sendMessage(`已经解禁${args.playerOrList}。`);
}
else player.sendMessage(`§c${args.playerOrList}没有被封禁。`);
}
else if(banData !== undefined) player.sendMessage(`§c${args.playerOrList}已经被封禁了。为了防止手滑,请先解禁后再封禁!`);
else if(args.duration === undefined) player.sendMessage("§c请给出封禁时长!");
else{
ban(/**@type {string}*/ (args.playerOrList), /**@type {number}*/ (args.duration));
player.dimension.runCommandAsync(`/kick ${args.playerOrList}`);
player.sendMessage(`成功封禁${args.playerOrList}。`);
}
}
return true;
}
});

/**封禁玩家。
* @param {Player} player
* @param {Player | string} playerOrName
* @param {number} durationSecond
* @param {string | undefined} [reason]
*/
export function ban(playerOrName, durationSecond, reason){
if(typeof playerOrName === "string"){
if(unbanList.includes(playerOrName)){
console.log(`Hit unban list: ${playerOrName}`);
return;
}
banRegister(playerOrName, durationSecond, reason);
console.warn(`Ban action is not taken because \`player\` get string "${playerOrName}".`);
}
else{
if(unbanList.includes(playerOrName.name)){
console.log(`Hit unban list: ${playerOrName.name}`);
return;
}
banRegister(playerOrName.name, durationSecond, reason);
banAction(playerOrName, reason, durationSecond);
}
}

/**记录封禁信息。
* @param {string} name
* @param {number} durationSecond
* @param {string} [reason]
* @param {string | undefined} [reason]
*/
export function ban(player, durationSecond, reason){
for(let i = 0; i < unbanList.length; i++) if(player.name === unbanList[i]) return;
if(durationSecond !== 0) world.setDynamicProperty(`b#${player.name}`, `${system.currentTick + durationSecond * 20}#${reason}`);
else world.setDynamicProperty(`b#${player.name}`, `#${reason}`);
banAction(player, reason, durationSecond);
function banRegister(name, durationSecond, reason){
for(let i = 0; i < unbanList.length; i++) if(name === unbanList[i]){
console.error(`Banregister: ${name} is already banned!`);
return;
}
if(durationSecond !== 0) world.setDynamicProperty(`b#${name}`, `${system.currentTick + durationSecond * 20}#${reason !== undefined ? reason : ""}`);
else world.setDynamicProperty(`b#${name}`, `#${reason !== undefined ? reason : ""}`);
}

/**执行封禁。
Expand All @@ -26,28 +102,37 @@ export function ban(player, durationSecond, reason){
function banAction(player, reason, durationSecond){
if(durationSecond === 0) system.run(()=>player.dimension.runCommand(`kick ${player.name} §c§l您已被封禁!§r§f${reason ? `原因: ${reason}` : ""}§c您的封禁是永久的。§f若要进行申诉,请将本截图发至群内并对您的行为做出诚实的解释。`));
else{
const
day = Math.floor(durationSecond / 86400),
hour = Math.floor((durationSecond - day * 86400) / 3600),
minute = Math.floor((durationSecond - day * 86400 - hour * 3600) / 60),
second = durationSecond - day * 86400 - hour * 3600 - minute * 60;
const [day, hour, minute, second] = getRestDuration(durationSecond);
system.run(()=>player.dimension.runCommand(`kick ${player.name} §c§l您已被封禁!§r§f${reason ? `原因: ${reason}` : ""}§c您的封禁时间剩余${day}${hour}小时${minute}分钟${second}秒。§f若要进行申诉,请将本截图发至群内并对您的行为做出诚实的解释。`));
}
}

/**`[day, hour, minute, second]`
* @returns {[number, number, number, number]}
*/
function getRestDuration(durationSecond){
const
day = Math.floor(durationSecond / 86400),
hour = Math.floor((durationSecond - day * 86400) / 3600),
minute = Math.floor((durationSecond - day * 86400 - hour * 3600) / 60),
second = durationSecond - day * 86400 - hour * 3600 - minute * 60;
return [day, hour, minute, second];
}

/**解封玩家。
* @param {Player} player
* @param {string} name
*/
export function unban(player){
const banData = world.getDynamicProperty(`b#${player.name}`);
if(banData !== undefined) world.setDynamicProperty(`b#${player.name}`, undefined);
else console.error(`${player.name} is not banned!`);
export function unban(name){
const banData = world.getDynamicProperty(`b#${name}`);
if(banData !== undefined) world.setDynamicProperty(`b#${name}`, undefined);
else console.error(`${name} is not banned!`);
}

world.afterEvents.playerSpawn.subscribe(data=>{
if(data.initialSpawn){
for(let i = 0; i < unbanList.length; i++) if(data.player.name === unbanList[i]){
unban(data.player);
console.warn(`List unbanned ${data.player.name}.`);
unban(data.player.name);
return;
}
const banData = /**@type {string | undefined}*/ (world.getDynamicProperty(`b#${data.player.name}`));
Expand All @@ -59,7 +144,7 @@ world.afterEvents.playerSpawn.subscribe(data=>{
else{
const remainingDurationSecond = Math.floor((durationTick - system.currentTick) / 20);
if(remainingDurationSecond > 0) banAction(data.player, banRaw.join("#"), remainingDurationSecond);
else unban(data.player);
else unban(data.player.name);
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions scripts/antiCheat/dupeFixes.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//@ts-check
import { BlockPermutation, ItemStack, world } from "@minecraft/server";
import { BlockPermutation, ItemStack, world } from "@minecraft/server";
import { dimensionIds } from "../common";

export function dupeFixesInit(){}

Expand All @@ -8,7 +8,7 @@ export function dupeFixesInit(){}
*/
world.afterEvents.pistonActivate.subscribe(data=>{
const methodName = "End Regen";
if(data.dimension.id === "minecraft:the_end" && data.piston.block.location.y <= 16){
if(data.dimension.id === dimensionIds[2] && data.piston.block.location.y <= 16){
const nearPlayers = data.dimension.getPlayers({
location: data.piston.block.location,
closest: 100,
Expand Down
3 changes: 1 addition & 2 deletions scripts/antiCheat/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//@ts-check
import { dupeFixesInit } from "./dupeFixes";
import { dupeFixesInit } from "./dupeFixes";
import { loopCommandsInit } from "./loopCommands";
import { banInit } from "./ban";

Expand Down
24 changes: 14 additions & 10 deletions scripts/antiCheat/loopCommands.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
//@ts-check
import { EntityComponentTypes, EntityInventoryComponent, GameMode, system, world } from "@minecraft/server";
import { Dimension, EntityComponentTypes, EntityInventoryComponent, GameMode, PlayerCursorInventoryComponent, system, world } from "@minecraft/server";
import { ban } from "./ban";
import { dimensionIds, retrieveDimension } from "../common";

export function loopCommandsInit(){}

const o = "minecraft:overworld", n = "minecraft:nether", e = "minecraft:the_end", wind = "minecraft:wind_charge_projectile", bWind = "minecraft:breeze_wind_charge_projectile";
const
o = retrieveDimension("o"),
n = retrieveDimension("n"),
e = retrieveDimension("e"),
wind = "minecraft:wind_charge_projectile",
bWind = "minecraft:breeze_wind_charge_projectile";

system.runInterval(()=>{
capY320(o, wind);
Expand All @@ -13,15 +18,15 @@ system.runInterval(()=>{
capY320(o, bWind);
capY320(n, bWind);
capY320(e, bWind);
}, 40);
}, 80);

system.runInterval(()=>{
const
csPlayers = world.getPlayers({excludeGameModes: [GameMode.survival, GameMode.adventure]}),
saPlayers = world.getPlayers({excludeGameModes: [GameMode.creative, GameMode.spectator]});
for(let i = 0; i < csPlayers.length; i++) if(!csPlayers[i].hasTag("dev")) ban(csPlayers[i], 604800, `非法获得${csPlayers[i].getGameMode() === GameMode.creative ? "创造" : "旁观"}模式。`);
for(let i = 0; i < saPlayers.length; i++){
if(saPlayers[i].isFlying) ban(csPlayers[i], 604800, `飞行。`);
if(saPlayers[i] && saPlayers[i].isFlying) ban(csPlayers[i], 604800, `飞行。`);
}
}, 4);

Expand All @@ -45,20 +50,20 @@ system.runInterval(()=>{
}, 2);

/**删除y超过世界建筑限制的风弹。
* @param {string} dimension
* @param {Dimension} dimension
* @param {string} type
*/
function capY320(dimension, type){
const entities = world.getDimension(dimension).getEntities({type});
const entities = dimension.getEntities({type});
for(let i = 0; i < entities.length; i++) if(entities[i].location.y >= 322) entities[i].remove();
}

/**删除违规实体。
* @param {string} dimension
* @param {Dimension} dimension
* @param {string} type
*/
function remove(dimension, type){
const entities = world.getDimension(dimension).getEntities({type});
const entities = dimension.getEntities({type});
for(let i = 0; i < entities.length; i++){
console.error(`Illegal entity ${type} found in ${dimension} ${entities[i].location.x.toFixed(1)} ${entities[i].location.y.toFixed(1)} ${entities[i].location.z.toFixed(1)}`);
entities[i].remove();
Expand All @@ -74,7 +79,6 @@ function removeSurvival(ids, banPlayer){
for(let i = 0; i < players.length; i++){
const
inventory = /**@type {EntityInventoryComponent | undefined}*/ (players[i].getComponent(EntityComponentTypes.Inventory)),
//@ts-ignore
cursor = /**@type {PlayerCursorInventoryComponent | undefined}*/ (players[i].getComponent(EntityComponentTypes.CursorInventory));
if(inventory && inventory.container){
const container = inventory.container;
Expand Down
20 changes: 20 additions & 0 deletions scripts/biome.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { registerCommand } from "./commandBase";
import { getBiome, getCoordinate } from "./common";

export function biomeInit(){}

registerCommand({
names: ["b", "biome", "qx", "swqx"],
description: "获得你现在所处位置的生物群系(可能不准确)。",
document: "使用了寻找最近的生物群系接口,通过遍历所有可能的生物群系,并选取最小的距离作为返回值。由于Mojang的奇怪接口bug,可能存在垂直生物群系不准确(如在地下某生物群系时得到地上的生物群系)的问题。值得注意的是,在地面看到的地貌和此处的生物群系可能不同,这不是接口的不准确性,而是Minecraft生成地貌时并不会完全忠于生物群系,而是在边界处有相当的模糊处理。",
args: [{
name: "showID",
optional: true,
type: "boolean"
}],
callback: async (_name, player, args)=>{
const [id, name] = await getBiome(player), [coord] = getCoordinate(player);
player.sendMessage(`坐标 (${coord.x}, ${coord.y}, ${coord.z}) 处于 ${name === undefined ? "虚空" : name}${args.showID ? `(${id})` : ""} 生物群系。`);
return true;
}
});
Loading

0 comments on commit 7e04cfd

Please sign in to comment.