mirror of
http://junepve.top:3000/chicrobot/CINC.git
synced 2026-10-29 21:41:29 +08:00
feat(SS) 添加游戏时间
This commit is contained in:
1 parent
ad84198db5
commit
2616dc21f1
5 files changed
+427
-3
No files matched your search
@@ -50,9 +50,12 @@ import CharacterClassTestScene from './scenes/testScenes/CharacterClassTestScene
|
|||||||
import WeaponTestScene from './scenes/testScenes/WeaponTestScene.js';
|
import WeaponTestScene from './scenes/testScenes/WeaponTestScene.js';
|
||||||
|
|
||||||
// 故事场景
|
// 故事场景
|
||||||
// 导入开天辟地
|
// 开天辟地
|
||||||
import PrimordialDevide from './scenes/storeScenes/PrimordialDevide.js';
|
import PrimordialDevide from './scenes/storeScenes/PrimordialDevide.js';
|
||||||
// 导入女娲造人
|
// 日月山川
|
||||||
|
import WorldTime from './scenes/storeScenes/WorldTime.js';
|
||||||
|
import WorldLand from './scenes/storeScenes/WorldLand.js';
|
||||||
|
// 女娲造人
|
||||||
import BreatheLife from './scenes/storeScenes/BreatheLife.js';
|
import BreatheLife from './scenes/storeScenes/BreatheLife.js';
|
||||||
|
|
||||||
// 创建游戏的最终配置对象
|
// 创建游戏的最终配置对象
|
||||||
@@ -63,6 +66,8 @@ const config = {
|
|||||||
// 指定游戏使用的场景列表,包括主场景和所有测试场景
|
// 指定游戏使用的场景列表,包括主场景和所有测试场景
|
||||||
scene: [
|
scene: [
|
||||||
PrimordialDevide,
|
PrimordialDevide,
|
||||||
|
WorldTime,
|
||||||
|
WorldLand,
|
||||||
BreatheLife,
|
BreatheLife,
|
||||||
|
|
||||||
// 测试场景
|
// 测试场景
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export default class PrimordialDevide extends Phaser.Scene {
|
|||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
super('PrimordialDevide')
|
super('PrimordialDevide')
|
||||||
this.nextScene = 'BreatheLife'
|
this.nextScene = 'WorldTime'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,134 @@
|
|||||||
|
/**
|
||||||
|
* WorldLand 场景类
|
||||||
|
*
|
||||||
|
* 初始引导场景,显示空白背景并在用户交互或自动延迟后
|
||||||
|
* 执行过渡动画切换到下一个场景
|
||||||
|
*/
|
||||||
|
import GameTimeManager from '../../systems/GameTimeManager.js'
|
||||||
|
|
||||||
|
export default class WorldLand extends Phaser.Scene {
|
||||||
|
/**
|
||||||
|
* 构造函数
|
||||||
|
* 初始化场景并设置场景键名为 'WorldLand'
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super('WorldLand')
|
||||||
|
this.nextScene = 'BreatheLife'
|
||||||
|
|
||||||
|
this.timeManager = new GameTimeManager() // 创建游戏时间管理器实例
|
||||||
|
|
||||||
|
this.UIDepth = 100 // UI层级深度,确保在其他元素之上
|
||||||
|
this.maskDepth = 99 // 黑夜遮罩层级,低于UI层级
|
||||||
|
|
||||||
|
}
|
||||||
|
create() {
|
||||||
|
// 设置场景背景颜色为深灰色
|
||||||
|
this.cameras.main.setBackgroundColor('#999999')
|
||||||
|
|
||||||
|
// 监听鼠标点击事件,点击后执行场景过渡动画
|
||||||
|
this.input.on('pointerdown', () => {
|
||||||
|
this.scene.start(this.nextScene);
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听键盘按键事件,按键后执行场景过渡动画
|
||||||
|
this.input.keyboard.on('keydown', () => {
|
||||||
|
this.scene.start(this.nextScene);
|
||||||
|
})
|
||||||
|
|
||||||
|
this.initDayNight(this.toGameTime('1999-12-30 23:57:00')) // 初始化时间,白天黑夜状态
|
||||||
|
this.initFrameRateText() // 初始化帧率显示文本
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 更新游戏时间
|
||||||
|
* 每帧调用,刷新游戏时间
|
||||||
|
*/
|
||||||
|
update() {
|
||||||
|
this.showFrameRate() // 显示当前帧率
|
||||||
|
this.updateGameTime() // 更新游戏时间
|
||||||
|
this.displayTime() // 显示当前游戏时间
|
||||||
|
this.updateDayNight() // 更新昼夜状态
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
initFrameRateText() {
|
||||||
|
// 创建帧率显示文本
|
||||||
|
this.frameRateText = this.add.text(
|
||||||
|
20, 60, '', {
|
||||||
|
fontSize: '20px',
|
||||||
|
fill: '#ffffff',
|
||||||
|
fontFamily: 'Arial'
|
||||||
|
}
|
||||||
|
).setScrollFactor(0).setDepth(this.UIDepth) // 固定文本,不随相机移动,UI层级
|
||||||
|
}
|
||||||
|
showFrameRate() {
|
||||||
|
// 获取当前帧率
|
||||||
|
const frameRate = this.game.loop.actualFps
|
||||||
|
// 更新帧率显示文本
|
||||||
|
this.frameRateText.setText(`Frame Rate: ${frameRate.toFixed(2)}`)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 初始化昼夜状态
|
||||||
|
* 设置初始为白天,添加事件监听切换状态
|
||||||
|
*/
|
||||||
|
initDayNight(gameTime) {
|
||||||
|
this.timeManager.init(gameTime) // 初始化时间管理器
|
||||||
|
// 创建时间显示文本
|
||||||
|
this.timeText = this.add.text(
|
||||||
|
20, 20, '', {
|
||||||
|
fontSize: '20px',
|
||||||
|
fill: '#ffffff',
|
||||||
|
fontFamily: 'Arial'
|
||||||
|
}
|
||||||
|
).setScrollFactor(0).setDepth(this.UIDepth) // 固定文本,不随相机移动,UI层级
|
||||||
|
// 添加黑夜遮罩
|
||||||
|
this.nightMask = this.add.rectangle(
|
||||||
|
0, 0,
|
||||||
|
this.cameras.main.width,
|
||||||
|
this.cameras.main.height,
|
||||||
|
0x000000
|
||||||
|
).setOrigin(0, 0).setScrollFactor(0).setDepth(this.maskDepth) // 固定遮罩,不随相机移动,遮罩层级
|
||||||
|
this.nightMask.alpha = 0 // 初始设置为透明
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 更新游戏时间
|
||||||
|
* 每帧调用,基于现实时间流逝更新游戏时间
|
||||||
|
*/
|
||||||
|
updateGameTime() {
|
||||||
|
this.timeManager.updateGameTime() // 使用时间管理器更新游戏时间
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取游戏中的日期
|
||||||
|
* 根据游戏时间戳计算游戏年月日时分秒,格式为YYYY-MM-DD HH:mm:ss
|
||||||
|
*/
|
||||||
|
getGameDate() {
|
||||||
|
return this.timeManager.getGameDate() // 使用时间管理器获取游戏日期
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 转换游戏时间字符串为游戏时间戳
|
||||||
|
* 接收时间字符串,格式为YYYY-MM-DD HH:mm:ss,返回游戏时间戳(单位:秒)
|
||||||
|
*/
|
||||||
|
toGameTime(gameTimeString) {
|
||||||
|
return this.timeManager.toGameTime(gameTimeString) // 使用时间管理器转换游戏时间
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 显示当前时间
|
||||||
|
* 每帧调用,更新显示时间
|
||||||
|
*/
|
||||||
|
displayTime() {
|
||||||
|
const timeString = this.getGameDate().dateString
|
||||||
|
const day = this.timeManager.getDayNightState() ? '白天' : '黑夜'
|
||||||
|
// 更新显示时间
|
||||||
|
this.timeText.setText(`${day} ${timeString}`)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 更新昼夜状态
|
||||||
|
* 每帧调用,根据游戏时间切换白天黑夜状态
|
||||||
|
*/
|
||||||
|
updateDayNight() {
|
||||||
|
const isDay = this.timeManager.updateDayNight()
|
||||||
|
// 根据昼夜状态更新遮罩
|
||||||
|
if (this.nightMask) {
|
||||||
|
this.nightMask.alpha = isDay ? 0 : 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
/**
|
||||||
|
* WorldLand 场景类
|
||||||
|
*
|
||||||
|
* 初始引导场景,显示空白背景并在用户交互或自动延迟后
|
||||||
|
* 执行过渡动画切换到下一个场景
|
||||||
|
*/
|
||||||
|
export default class WorldTime extends Phaser.Scene {
|
||||||
|
/**
|
||||||
|
* 构造函数
|
||||||
|
* 初始化场景并设置场景键名为 'WorldTime'
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super('WorldTime')
|
||||||
|
this.nextScene = 'WorldLand'
|
||||||
|
|
||||||
|
this.gameTime = 0 // 游戏中的时间戳(单位:秒)
|
||||||
|
// 固定为60秒/分钟,60分钟/小时,24小时/天,30天/月,12月/年
|
||||||
|
this.minuteSec = 60
|
||||||
|
this.hourSec = 60 * this.minuteSec
|
||||||
|
this.daySec = 24 * this.hourSec
|
||||||
|
this.monthSec = 30 * this.daySec
|
||||||
|
this.yearSec = 12 * this.monthSec
|
||||||
|
|
||||||
|
this.lastRealTime = 0 // 上一次更新的现实时间戳(毫秒)
|
||||||
|
this.gameTimeUpdateInterval = 1000/60 // 游戏中的每秒时间更新间隔(毫秒)
|
||||||
|
|
||||||
|
this.isDay = true // 昼夜状态
|
||||||
|
|
||||||
|
this.UIDepth = 100 // UI层级深度,确保在其他元素之上
|
||||||
|
this.maskDepth = 99 // 黑夜遮罩层级,低于UI层级
|
||||||
|
|
||||||
|
}
|
||||||
|
create() {
|
||||||
|
// 设置场景背景颜色为深灰色
|
||||||
|
this.cameras.main.setBackgroundColor('#999999')
|
||||||
|
|
||||||
|
// 监听鼠标点击事件,点击后执行场景过渡动画
|
||||||
|
this.input.on('pointerdown', () => {
|
||||||
|
this.scene.start(this.nextScene);
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听键盘按键事件,按键后执行场景过渡动画
|
||||||
|
this.input.keyboard.on('keydown', () => {
|
||||||
|
this.scene.start(this.nextScene);
|
||||||
|
})
|
||||||
|
|
||||||
|
this.initDayNight(this.toGameTime('2000-01-01 17:57:00')) // 初始化时间,白天黑夜状态
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 更新游戏时间
|
||||||
|
* 每帧调用,刷新游戏时间
|
||||||
|
*/
|
||||||
|
update() {
|
||||||
|
this.updateGameTime() // 更新游戏时间
|
||||||
|
this.displayTime() // 显示当前游戏时间
|
||||||
|
this.updateDayNight() // 更新昼夜状态
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 初始化昼夜状态
|
||||||
|
* 设置初始为白天,添加事件监听切换状态
|
||||||
|
*/
|
||||||
|
initDayNight(gameTime) {
|
||||||
|
// 初始更新时间戳为当前现实时间,注意不要使用this.time.now,它是Phaser的时间戳,不是现实时间
|
||||||
|
this.lastRealTime = Date.now()
|
||||||
|
this.isDay = true // 设置初始为白天
|
||||||
|
this.gameTime = gameTime // 设置游戏初始时间
|
||||||
|
// 创建时间显示文本
|
||||||
|
this.timeText = this.add.text(
|
||||||
|
20, 20, '', {
|
||||||
|
fontSize: '20px',
|
||||||
|
fill: '#ffffff',
|
||||||
|
fontFamily: 'Arial'
|
||||||
|
}
|
||||||
|
).setScrollFactor(0).setDepth(this.UIDepth) // 固定文本,不随相机移动,UI层级
|
||||||
|
// 添加黑夜遮罩
|
||||||
|
this.nightMask = this.add.rectangle(
|
||||||
|
0, 0,
|
||||||
|
this.cameras.main.width,
|
||||||
|
this.cameras.main.height,
|
||||||
|
0x000000
|
||||||
|
).setOrigin(0, 0).setScrollFactor(0).setDepth(this.maskDepth) // 固定遮罩,不随相机移动,遮罩层级
|
||||||
|
this.nightMask.alpha = 0 // 初始设置为透明
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 更新游戏时间
|
||||||
|
* 每帧调用,基于现实时间流逝更新游戏时间
|
||||||
|
*/
|
||||||
|
updateGameTime() {
|
||||||
|
// 获取当前现实时间戳
|
||||||
|
const currentRealTime = Date.now()
|
||||||
|
// 计算与上次更新的时间差(毫秒)
|
||||||
|
const deltaRealTime = currentRealTime - this.lastRealTime
|
||||||
|
if (deltaRealTime <= this.gameTimeUpdateInterval) { // 小于更新间隔,不更新时间
|
||||||
|
return
|
||||||
|
}else {
|
||||||
|
let addSec = deltaRealTime / this.gameTimeUpdateInterval // 计算增加的秒数
|
||||||
|
this.gameTime += addSec // 更新游戏时间
|
||||||
|
this.lastRealTime = currentRealTime // 刷新更新时间戳
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取游戏中的日期
|
||||||
|
* 根据游戏时间戳计算游戏年月日时分秒,格式为YYYY-MM-DD HH:mm:ss
|
||||||
|
*/
|
||||||
|
getGameDate() {
|
||||||
|
// 计算当前时间的年、月、日、时、分、秒
|
||||||
|
const year = Math.floor(this.gameTime / this.yearSec)
|
||||||
|
const month = Math.floor((this.gameTime % this.yearSec) / this.monthSec)+1
|
||||||
|
const day = Math.floor((this.gameTime % this.monthSec) / this.daySec)+1
|
||||||
|
const hour = Math.floor((this.gameTime % this.daySec) / this.hourSec)
|
||||||
|
const minute = Math.floor((this.gameTime % this.hourSec) / this.minuteSec)
|
||||||
|
const second = Math.floor(this.gameTime % this.minuteSec)
|
||||||
|
// 格式化日期字符串
|
||||||
|
const dateString = `${year}-${month < 10 ? '0' : ''}${month}-${day < 10 ? '0' : ''}${day} ${hour < 10 ? '0' : ''}${hour}:${minute < 10 ? '0' : ''}${minute}:${second < 10 ? '0' : ''}${second}`
|
||||||
|
const formatDate = {
|
||||||
|
year, month, day, hour, minute, second ,
|
||||||
|
dateString,
|
||||||
|
}
|
||||||
|
return formatDate
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 转换游戏时间字符串为游戏时间戳
|
||||||
|
* 接收时间字符串,格式为YYYY-MM-DD HH:mm:ss,返回游戏时间戳(单位:秒)
|
||||||
|
*/
|
||||||
|
toGameTime(gameTimeString) {
|
||||||
|
// 解析时间字符串为秒数
|
||||||
|
const [year, month, day, hour, minute, second] = gameTimeString.split(/[- :]/).map(Number)
|
||||||
|
// 计算游戏时间戳
|
||||||
|
return year * this.yearSec + (month - 1) * this.monthSec + (day - 1) * this.daySec + hour * this.hourSec + minute * this.minuteSec + second
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 显示当前时间
|
||||||
|
* 每帧调用,更新显示时间
|
||||||
|
*/
|
||||||
|
displayTime() {
|
||||||
|
const timeString = this.getGameDate().dateString
|
||||||
|
const day = this.isDay ? '白天' : '黑夜'
|
||||||
|
// 更新显示时间
|
||||||
|
this.timeText.setText(`${day} ${timeString}`)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 更新昼夜状态
|
||||||
|
* 每帧调用,根据游戏时间切换白天黑夜状态
|
||||||
|
*/
|
||||||
|
updateDayNight() {
|
||||||
|
const hour = this.getGameDate().hour
|
||||||
|
if (hour >= 6 && hour < 18) {
|
||||||
|
this.isDay = true
|
||||||
|
// 白天:隐藏黑夜遮罩
|
||||||
|
if (this.nightMask) {
|
||||||
|
this.nightMask.alpha = 0
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
this.isDay = false
|
||||||
|
// 黑夜:显示黑夜遮罩
|
||||||
|
if (this.nightMask) {
|
||||||
|
this.nightMask.alpha = 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
/**
|
||||||
|
* GameTimeManager 游戏时间管理类
|
||||||
|
*
|
||||||
|
* 负责管理游戏中的时间系统,包括:
|
||||||
|
* 1. 游戏时间的更新和计算
|
||||||
|
* 2. 游戏时间与现实时间的转换
|
||||||
|
* 3. 游戏日期的获取
|
||||||
|
* 4. 昼夜状态的管理
|
||||||
|
*/
|
||||||
|
export default class GameTimeManager {
|
||||||
|
/**
|
||||||
|
* 构造函数
|
||||||
|
* 初始化时间管理系统
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
this.gameTime = 0 // 游戏中的时间戳(单位:秒)
|
||||||
|
// 固定为60秒/分钟,60分钟/小时,24小时/天,30天/月,12月/年
|
||||||
|
this.minuteSec = 60
|
||||||
|
this.hourSec = 60 * this.minuteSec
|
||||||
|
this.daySec = 24 * this.hourSec
|
||||||
|
this.monthSec = 30 * this.daySec
|
||||||
|
this.yearSec = 12 * this.monthSec
|
||||||
|
|
||||||
|
this.lastRealTime = 0 // 上一次更新的现实时间戳(毫秒)
|
||||||
|
this.gameTimeUpdateInterval = 1000/60 // 游戏中的每秒时间更新间隔(毫秒)
|
||||||
|
|
||||||
|
this.isDay = true // 昼夜状态
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化时间系统
|
||||||
|
* @param {number} initialGameTime - 初始游戏时间戳
|
||||||
|
*/
|
||||||
|
init(initialGameTime) {
|
||||||
|
this.lastRealTime = Date.now() // 初始更新时间戳为当前现实时间
|
||||||
|
this.isDay = true // 设置初始为白天
|
||||||
|
this.gameTime = initialGameTime // 设置游戏初始时间
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新游戏时间
|
||||||
|
* 每帧调用,刷新游戏时间
|
||||||
|
*/
|
||||||
|
updateGameTime() {
|
||||||
|
// 获取当前现实时间戳
|
||||||
|
const currentRealTime = Date.now()
|
||||||
|
// 计算与上次更新的时间差(毫秒)
|
||||||
|
const deltaRealTime = currentRealTime - this.lastRealTime
|
||||||
|
if (deltaRealTime <= this.gameTimeUpdateInterval) { // 小于更新间隔,不更新时间
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
let addSec = deltaRealTime / this.gameTimeUpdateInterval // 计算增加的秒数
|
||||||
|
this.gameTime += addSec // 更新游戏时间
|
||||||
|
this.lastRealTime = currentRealTime // 刷新更新时间戳
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取游戏中的日期
|
||||||
|
* 根据游戏时间戳计算游戏年月日时分秒,格式为YYYY-MM-DD HH:mm:ss
|
||||||
|
*/
|
||||||
|
getGameDate() {
|
||||||
|
// 计算当前时间的年、月、日、时、分、秒
|
||||||
|
const year = Math.floor(this.gameTime / this.yearSec)
|
||||||
|
const month = Math.floor((this.gameTime % this.yearSec) / this.monthSec)+1
|
||||||
|
const day = Math.floor((this.gameTime % this.monthSec) / this.daySec)+1
|
||||||
|
const hour = Math.floor((this.gameTime % this.daySec) / this.hourSec)
|
||||||
|
const minute = Math.floor((this.gameTime % this.hourSec) / this.minuteSec)
|
||||||
|
const second = Math.floor(this.gameTime % this.minuteSec)
|
||||||
|
// 格式化日期字符串
|
||||||
|
const dateString = `${year}-${month < 10 ? '0' : ''}${month}-${day < 10 ? '0' : ''}${day} ${hour < 10 ? '0' : ''}${hour}:${minute < 10 ? '0' : ''}${minute}:${second < 10 ? '0' : ''}${second}`
|
||||||
|
const formatDate = {
|
||||||
|
year, month, day, hour, minute, second ,
|
||||||
|
dateString,
|
||||||
|
}
|
||||||
|
return formatDate
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换游戏时间字符串为游戏时间戳
|
||||||
|
* 接收时间字符串,格式为YYYY-MM-DD HH:mm:ss,返回游戏时间戳(单位:秒)
|
||||||
|
*/
|
||||||
|
toGameTime(gameTimeString) {
|
||||||
|
// 解析时间字符串为秒数
|
||||||
|
const [year, month, day, hour, minute, second] = gameTimeString.split(/[- :]/).map(Number)
|
||||||
|
// 计算游戏时间戳
|
||||||
|
return year * this.yearSec + (month - 1) * this.monthSec + (day - 1) * this.daySec + hour * this.hourSec + minute * this.minuteSec + second
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新昼夜状态
|
||||||
|
* 每帧调用,根据游戏时间切换白天黑夜状态
|
||||||
|
*/
|
||||||
|
updateDayNight() {
|
||||||
|
const hour = this.getGameDate().hour
|
||||||
|
if (hour >= 6 && hour < 18) {
|
||||||
|
this.isDay = true
|
||||||
|
} else {
|
||||||
|
this.isDay = false
|
||||||
|
}
|
||||||
|
return this.isDay
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前昼夜状态
|
||||||
|
*/
|
||||||
|
getDayNightState() {
|
||||||
|
return this.isDay
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前游戏时间
|
||||||
|
*/
|
||||||
|
getGameTime() {
|
||||||
|
return this.gameTime
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置游戏时间
|
||||||
|
*/
|
||||||
|
setGameTime(gameTime) {
|
||||||
|
this.gameTime = gameTime
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user