feat: add in-game social test lab

This commit is contained in:
ANG-Server
2026-07-22 12:16:31 +08:00
parent fe52ab1696
commit a3341b6a3b
19 changed files with 827 additions and 14 deletions

View File

@@ -0,0 +1,92 @@
import { Type } from 'class-transformer';
import { IsBoolean, IsIn, IsNotEmpty, IsNumber, IsOptional, IsString, Length, Matches, Max, Min, ValidateIf } from 'class-validator';
import { MALL_SKIN_ITEMS } from '../mall/mall_catalog';
export const TEST_LAB_MAP_IDS = ['whale_port', 'work_zone', 'whale_cafe'] as const;
export type TestLabMapId = (typeof TEST_LAB_MAP_IDS)[number];
export const TEST_LAB_SKIN_IDS = MALL_SKIN_ITEMS.map((item) => item.skinId).filter((skinId): skinId is string => Boolean(skinId));
const TEST_LAB_NICKNAME_PATTERN = /^[\u4E00-\u9FFF A-Za-z0-9_-]+$/;
export class CreateTestLabActorDto {
@IsString()
@IsNotEmpty()
@Length(1, 32)
@Matches(TEST_LAB_NICKNAME_PATTERN, { message: '昵称仅支持中文、字母、数字、空格、下划线和连字符' })
nickname: string;
@IsIn(TEST_LAB_MAP_IDS)
mapId: TestLabMapId;
@Type(() => Number)
@IsNumber()
@Min(-8192)
@Max(8192)
x: number;
@Type(() => Number)
@IsNumber()
@Min(-8192)
@Max(8192)
y: number;
@IsOptional()
@IsIn(TEST_LAB_SKIN_IDS)
skinId?: string;
}
export class UpdateTestLabActorDto {
@IsOptional()
@IsBoolean()
online?: boolean;
@ValidateIf((value) => value.mapId !== undefined)
@IsIn(TEST_LAB_MAP_IDS)
mapId?: TestLabMapId;
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(-8192)
@Max(8192)
x?: number;
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(-8192)
@Max(8192)
y?: number;
@IsOptional()
@IsIn(TEST_LAB_SKIN_IDS)
skinId?: string;
}
export class TestLabMessageDto {
@IsIn(['local', 'global', 'private'])
scope: 'local' | 'global' | 'private';
@IsString()
@IsNotEmpty()
@Length(1, 1000)
content: string;
@ValidateIf((value) => value.scope === 'private')
@IsString()
@IsNotEmpty()
targetUserId?: string;
}
export class TestLabSocialActionDto {
@IsIn(['friend_request', 'friend_accept', 'friend_reject', 'block'])
action: 'friend_request' | 'friend_accept' | 'friend_reject' | 'block';
@IsString()
@IsNotEmpty()
targetUserId: string;
}
export class TestLabRoomPolicyDto {
@IsIn(['friends', 'public', 'closed'])
roomVisitPolicy: 'friends' | 'public' | 'closed';
}