Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export default ts.config(
'no-empty': 'off',
'no-console': 'off',
'no-undef': 'off',
'no-var': 'off',
'prefer-const': 'warn',
'lines-between-class-members': 'off',
'@typescript-eslint/no-explicit-any': 'off',
Expand Down
24 changes: 13 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@
"@formatjs/intl-locale": "^4.2.11",
"@formatjs/intl-numberformat": "^8.15.4",
"@formatjs/intl-pluralrules": "^5.4.4",
"@minecraft/server": "2.1.0-beta.1.21.90-stable",
"@minecraft/server-gametest": "1.0.0-beta.1.21.90-stable",
"@minecraft/server-net": "1.0.0-beta.1.21.90-stable",
"@minecraft/server-ui": "2.1.0-beta.1.21.90-stable",
"@minecraft/vanilla-data": "1.21.90",
"@minecraft/server": "2.4.0-beta.1.21.120-stable",
"@minecraft/server-gametest": "1.0.0-beta.1.21.120-stable",
"@minecraft/server-net": "1.0.0-beta.1.21.120-stable",
"@minecraft/server-ui": "2.1.0-beta.1.21.120-stable",
"@minecraft/vanilla-data": "1.21.120",
"async-mutex": "^0.5.0"
},
"resolutions": {
"@minecraft/server": "2.1.0-beta.1.21.90-stable",
"@minecraft/server-gametest": "1.0.0-beta.1.21.90-stable",
"@minecraft/server-net": "1.0.0-beta.1.21.90-stable",
"@minecraft/server-ui": "2.1.0-beta.1.21.90-stable",
"@minecraft/vanilla-data": "1.21.90"
"@minecraft/server": "2.4.0-beta.1.21.120-stable",
"@minecraft/server-gametest": "1.0.0-beta.1.21.120-stable",
"@minecraft/server-net": "1.0.0-beta.1.21.120-stable",
"@minecraft/server-ui": "2.1.0-beta.1.21.120-stable",
"@minecraft/vanilla-data": "1.21.120"
},
"devDependencies": {
"@eslint/js": "^9.29.0",
Expand Down Expand Up @@ -57,7 +57,9 @@
"printWidth": 120,
"endOfLine": "crlf",
"quoteProps": "consistent",
"plugins": [],
"plugins": [
"prettier-plugin-jsdoc"
],
"jsdocTagsOrder": "{\"template\": 24.5}"
},
"packageManager": "yarn@4.9.1",
Expand Down
12 changes: 6 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { system } from '@minecraft/server'
// Takes too much to load dynamically which results in interrupted error
import 'lib/assets/intl-global-object'

system.beforeEvents.startup.subscribe(() => {
system.run(() => {
if (__TEST__) import('./test/loader')
else import('./modules/loader')
})
import 'lib/assets/intl'

import('./modules/loader').catch((e: unknown) => {
console.error('Loading error', e)
})
102 changes: 51 additions & 51 deletions src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,54 +5,54 @@ import 'lib/load/message1'
import 'lib/database/properties'

// Database
export * from 'lib/database/inventory'
export * from 'lib/database/player'
export * from 'lib/database/scoreboard'
export * from 'lib/database/utils'

// Command
export * from 'lib/command/index'

// Lib
export * from 'lib/roles'
export * from 'lib/util'
export * from 'lib/vector'

export * from 'lib/action'
export * from 'lib/cooldown'
export * from 'lib/enchantments'
export * from 'lib/event-signal'
export * from 'lib/i18n/lang'
export * from 'lib/location'
export * from 'lib/mail'
export * from 'lib/player-join'
export * from 'lib/portals'
export * from 'lib/rpg/airdrop'
export * from 'lib/rpg/boss'
export * from 'lib/rpg/leaderboard'
export * from 'lib/rpg/loot-table'
export * from 'lib/rpg/menu'
export * from 'lib/settings'
export * from 'lib/sidebar'
export * from 'lib/temporary'
export * from 'lib/utils/game'
export * from 'lib/utils/ms'
export * from 'lib/utils/search'

// Region
export * from 'lib/region/index'

// Form
export * from 'lib/form/action'
export * from 'lib/form/array'
export * from 'lib/form/chest'
export * from 'lib/form/message'
export * from 'lib/form/modal'
export * from 'lib/form/npc'
export * from 'lib/form/utils'

// Extension exports
export * from 'lib/extensions/extend'
export * from 'lib/extensions/item-stack'
export * from 'lib/extensions/system'
export * from 'lib/load/extensions'
import 'lib/database/inventory'
import 'lib/database/player'
import 'lib/database/scoreboard'
import 'lib/database/utils'

// // Command
import 'lib/command/index'

// // Lib
// export * from 'lib/roles'
// export * from 'lib/util'
// export * from 'lib/vector'

// export * from 'lib/action'
// export * from 'lib/cooldown'
// export * from 'lib/enchantments'
// export * from 'lib/event-signal'
// export * from 'lib/i18n/lang'
// export * from 'lib/location'
// export * from 'lib/mail'
// export * from 'lib/player-join'
// export * from 'lib/portals'
// export * from 'lib/rpg/airdrop'
// export * from 'lib/rpg/boss'
// export * from 'lib/rpg/leaderboard'
// export * from 'lib/rpg/loot-table'
// export * from 'lib/rpg/menu'
// export * from 'lib/settings'
// export * from 'lib/sidebar'
// export * from 'lib/temporary'
// export * from 'lib/utils/game'
// export * from 'lib/utils/ms'
// export * from 'lib/utils/search'

// // Region
// export * from 'lib/region/index'

// // Form
// export * from 'lib/form/action'
// export * from 'lib/form/array'
// export * from 'lib/form/chest'
// export * from 'lib/form/message'
// export * from 'lib/form/modal'
// export * from 'lib/form/npc'
// export * from 'lib/form/utils'

// // Extension exports
// export * from 'lib/extensions/extend'
// export * from 'lib/extensions/item-stack'
// export * from 'lib/extensions/system'
// export * from 'lib/load/extensions'
6 changes: 6 additions & 0 deletions src/lib/achievements/achievement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import { i18n } from 'lib/i18n/text'
import { isNotPlaying } from 'lib/utils/game'
import { Rewards } from 'lib/utils/rewards'

declare module '@minecraft/server' {
interface PlayerDatabase {
achivs?: Achievement.DB
}
}

export namespace Achievement {
export interface DBSingle<T = unknown> {
id: string
Expand Down
29 changes: 29 additions & 0 deletions src/lib/anticheat/anti-piston-abuse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { system, world } from '@minecraft/server'
import { MinecraftBlockTypes } from '@minecraft/vanilla-data'
import { Vec } from 'lib/vector'
import { antiCheatLog } from './log-provider'

world.afterEvents.pistonActivate.subscribe(event => {
const locations = event.piston.getAttachedBlocksLocations()

system.runTimeout(
() => {
if (!event.block.isValid) return

for (const location of locations) {
const block = event.block.dimension.getBlock(location)
if (block?.typeId !== MinecraftBlockTypes.Hopper) continue

const nearbyPlayers = event.block.dimension.getPlayers({ location: event.block.location, maxDistance: 20 })
const nearbyPlayersNames = nearbyPlayers.map(e => e.name).join('\n')

antiCheatLog(`ПОРШЕНЬ ДЮП ${Vec.string(event.block.location)}\n${nearbyPlayersNames}`)

event.block.dimension.createExplosion(event.block.location, 5, { breaksBlocks: true })
return
}
},
'piston dupe prevent',
2,
)
})
22 changes: 22 additions & 0 deletions src/lib/anticheat/anti-wither-bedrock-kill.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { world } from '@minecraft/server'
import { MinecraftBlockTypes, MinecraftEntityTypes } from '@minecraft/vanilla-data'
import { Vec } from 'lib/vector'
import { antiCheatLog } from './log-provider'

world.afterEvents.entitySpawn.subscribe(event => {
const { entity } = event

if (entity.typeId !== MinecraftEntityTypes.Wither) return

const { location } = entity
const block = entity.dimension.getBlock(location)

if (block?.typeId !== MinecraftBlockTypes.Bedrock) return

const nearbyPlayers = event.entity.dimension.getPlayers({ location, maxDistance: 20 })
const nearbyPlayersNames = nearbyPlayers.map(e => e.name).join('\n')

antiCheatLog(`ОБНАРУЖЕН АБУЗ ВИЗЕРА ${Vec.string(location)}\n${nearbyPlayersNames}`)

entity.remove()
})
15 changes: 15 additions & 0 deletions src/lib/anticheat/ban.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { system, world } from '@minecraft/server'

new Command('ban')
.setDescription('Кикает и убирает игрока из вайтлиста')
.setPermissions('helper')
.string('playerName')
.executes((ctx, name) => {
system.delay(() => {
world.overworld.runCommand(`allowlist remove ${name}`)
world.overworld.runCommand(
`kick ${name} "Вы были забанены\nОбжаловать можно через бот техподдержки: @FolkLore_Support_bot"`,
)
})
ctx.player.success()
})
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { system, world } from '@minecraft/server'
import { MinecraftItemTypes } from '@minecraft/vanilla-data'
import { actionGuard, ActionGuardOrder, isNotPlaying } from 'lib'
import { createLogger } from 'lib/utils/logger'

import { antiCheatLogger } from './log-provider'
import { ActionGuardOrder } from 'lib/region'
import { actionGuard } from 'lib/region'
import { isNotPlaying } from 'lib/utils/game'

const forbiddenItems: string[] = [
MinecraftItemTypes.Barrier,
Expand All @@ -13,7 +16,9 @@ const forbiddenItems: string[] = [
MinecraftItemTypes.RepeatingCommandBlock,
]

const logger = createLogger('AntiCheat')
const logger = antiCheatLogger

// TODO Use inventorySlotChange + scan on startup and player join

function interval() {
try {
Expand Down
53 changes: 53 additions & 0 deletions src/lib/anticheat/freeze.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { InputPermissionCategory, Player, system } from '@minecraft/server'
import { ActionbarPriority } from 'lib/extensions/on-screen-display'
import { selectPlayer } from 'lib/form/select-player'

new Command('freeze')
.setDescription('Останавливает движение игрока до unfreeze')
.setPermissions('helper')
.string('playerName')
.executes((ctx, name) => {
if (name) {
const player = Player.getByName(name)
if (!player) return ctx.error('Player not found')

system.delay(() => {
player.inputPermissions.setPermissionCategory(InputPermissionCategory.Movement, false)
player.onScreenDisplay.setActionBar('§cВы были заморожены', ActionbarPriority.Highest)
})
return ctx.reply('Успешно')
}
selectPlayer(ctx.player, 'заморозить').then(({ player }) => {
if (!player) return ctx.player.fail('Выберите онлайн игрока')

player.inputPermissions.setPermissionCategory(InputPermissionCategory.Movement, false)
player.onScreenDisplay.setActionBar('§cВы были заморожены', ActionbarPriority.Highest)
ctx.player.success()
})
})

new Command('unfreeze')
.setDescription('Возвращает движение игроку')
.setPermissions('helper')

.string('playerName')
.executes((ctx, name) => {
if (name) {
const player = Player.getByName(name)
if (!player) return ctx.error('Player not found')

system.delay(() => {
player.inputPermissions.setPermissionCategory(InputPermissionCategory.Movement, true)
player.onScreenDisplay.setActionBar('§aВы были разморожены', ActionbarPriority.Highest)
})
return ctx.reply('Успешно')
}
selectPlayer(ctx.player, 'заморозить').then(({ id }) => {
const player = Player.getById(id)
if (!player) return ctx.player.fail('Выберите онлайн игрока')

player.inputPermissions.setPermissionCategory(InputPermissionCategory.Movement, true)
player.onScreenDisplay.setActionBar('§aВы были разморожены', ActionbarPriority.Highest)
ctx.player.success()
})
})
16 changes: 16 additions & 0 deletions src/lib/anticheat/log-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { createLogger } from 'lib/utils/logger'

export const antiCheatLogger = createLogger('anticheat')

export function antiCheatLog(text: string) {
if (!log) return antiCheatLogger.warn('No provider: ', text)

antiCheatLogger.warn(text)
log(text)
}

let log: null | ((text: string) => void) = null

export function registerAntiCheatLogProvider(provider: typeof log) {
log = provider
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { system, world } from '@minecraft/server'
import { DEFAULT_ROLE, is, ROLES, Settings } from 'lib'

import { defaultLang } from 'lib/assets/lang'
import { noI18n } from 'lib/i18n/text'
import { DEFAULT_ROLE, is, ROLES } from 'lib/roles'
import { Settings } from 'lib/settings'
import { onLoad } from 'lib/utils/load-ref'
import { createLogger } from 'lib/utils/logger'

// Delay execution to move whitelist settings to the end of the settings menu
Expand Down Expand Up @@ -37,7 +40,7 @@ system.delay(() => {
}
})

system.delay(() => {
onLoad(() => {
if (whitelist.enabled) {
logger.info('To disable, use /scriptevent whitelist:disable')
}
Expand Down
3 changes: 3 additions & 0 deletions src/lib/assets/intl-global-object.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//@ts-expect-error Define global intl if not defined
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
globalThis.Intl ??= {}
Loading