Skip to content

Commit

Permalink
更改强度设置模式
Browse files Browse the repository at this point in the history
  • Loading branch information
hyperzlib committed Jul 8, 2024
1 parent 2f62dfc commit 96861d9
Show file tree
Hide file tree
Showing 12 changed files with 132 additions and 120 deletions.
22 changes: 11 additions & 11 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ GET /api/game/{clientId}
"code": "OK",
"gameConfig": {
"strength": {
"minStrength": 1, // 最小随机强度
"maxStrength": 10, // 最大随机强度
"strength": 1, // 基础强度
"randomStrength": 10, // 随机强度,最终强度 = 基础强度 + random(0, 随机强度)
"minInterval": 10, // 最小随机间隔
"maxInterval": 15 // 最大随机间隔
"maxInterval": 15, // 最大随机间隔
"bChannelMultiplier": 1.0, // B通道强度倍数,如果存在此参数,则会启动B通道
},
"pulseId": "pulse-1" // 脉冲ID
},
Expand Down Expand Up @@ -78,8 +79,8 @@ GET /api/game/{clientId}/strength_info
"status": 1,
"code": "OK",
"strengthConfig": { // 强度配置,同上
"minStrength": 5,
"maxStrength": 10,
"strength": 5,
"randomStrength": 10,
"minInterval": 10,
"maxInterval": 15
}
Expand All @@ -101,16 +102,15 @@ POST /api/game/{clientId}/strength_info

```typescript
type SetStrengthConfigRequest = {
minStrength?: {
add?: number; // 增加最低随机强度(基础强度)
strength?: {
add?: number; // 增加基础强度
sub?: number; // 减少强度
set?: number; // 设置强度
},
maxStrength?: {
add?: number; // 增加最高随机强度
randomStrength?: {
add?: number; // 增加随机强度
sub?: number; // 减少强度
set?: number; // 设置强度
keep?: boolean; // 是否保持最低强度不变,默认会根据最低强度的变化调整最高强度
},
minInterval?: {
set?: number; // 设置最低随机间隔
Expand All @@ -125,7 +125,7 @@ type SetStrengthConfigRequest = {
```json5
{
"minStrength": {
"strength": {
"add": 1
}
}
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/apis/socketApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ export type StrengthInfo = {
limit: number;
};

export type RandomStrengthConfig = {
minStrength: number;
maxStrength: number;
export type GameStrengthConfig = {
strength: number;
randomStrength: number;
minInterval: number;
maxInterval: number;
bChannelMultiplier?: number;
}

export type CoyoteLiveGameConfig = {
strength: RandomStrengthConfig;
strength: GameStrengthConfig;
pulseId: string;
}

Expand Down
45 changes: 32 additions & 13 deletions frontend/src/pages/Controller.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { handleApiResponse } from '../utils/response';
const CLIENT_ID_STORAGE_KEY = 'liveGameClientId';
const state = reactive({
valLow: 5,
valHigh: 10,
valLimit: 50,
strengthVal: 5,
randomStrengthVal: 5,
strengthLimit: 20,
randomFreqLow: 10,
randomFreqHigh: 15,
Expand Down Expand Up @@ -43,8 +43,8 @@ const gameConfig = computed<CoyoteLiveGameConfig>({
get: () => {
return {
strength: {
minStrength: state.valLow,
maxStrength: state.valHigh,
strength: state.strengthVal,
randomStrength: state.randomStrengthVal,
minInterval: state.randomFreqLow,
maxInterval: state.randomFreqHigh,
bChannelMultiplier: state.bChannelEnabled ? state.bChannelMultiple : undefined,
Expand All @@ -53,8 +53,8 @@ const gameConfig = computed<CoyoteLiveGameConfig>({
};
},
set: (value) => {
state.valLow = value.strength.minStrength;
state.valHigh = value.strength.maxStrength;
state.strengthVal = value.strength.strength;
state.randomStrengthVal = value.strength.randomStrength;
state.randomFreqLow = value.strength.minInterval;
state.randomFreqHigh = value.strength.maxInterval;
state.bChannelEnabled = typeof value.strength.bChannelMultiplier === 'number';
Expand All @@ -63,6 +63,12 @@ const gameConfig = computed<CoyoteLiveGameConfig>({
}
});
const chartVal = computed(() => ({
valLow: state.strengthVal,
valHigh: Math.min(state.strengthVal + state.randomStrengthVal, state.strengthLimit),
valLimit: state.strengthLimit,
}))
const randomFreq = computed({
get: () => {
return [state.randomFreqLow, state.randomFreqHigh];
Expand Down Expand Up @@ -142,7 +148,7 @@ const initWebSocket = async () => {
});
wsClient.on('strengthChanged', (strength) => {
state.valLimit = strength.limit;
state.strengthLimit = strength.limit;
});
wsClient.on('configUpdated', (config) => {
Expand Down Expand Up @@ -324,7 +330,7 @@ watch(gameConfig, () => {
<Toast></Toast>
<div class="flex flex-col lg:flex-row items-center lg:items-start gap-8">
<div class="flex">
<StatusChart v-model:val-low="state.valLow" v-model:val-high="state.valHigh" :val-limit="state.valLimit" :running="state.gameStarted" />
<StatusChart v-model:val-low="chartVal.valLow" v-model:val-high="chartVal.valHigh" :val-limit="chartVal.valLimit" :running="state.gameStarted" readonly />
</div>

<Card class="controller-panel flex-grow-1 flex-shrink-1 w-full">
Expand Down Expand Up @@ -359,11 +365,8 @@ watch(gameConfig, () => {
</template>

<template #content>
<span class="opacity-80 block mb-4">
强度请点击仪表盘上的数字进行更改
</span>
<div class="w-full flex flex-col md:flex-row items-top lg:items-center gap-2 lg:gap-8 mb-8 lg:mb-4">
<label class="font-semibold w-30 flex-shrink-0">强度跳变频率</label>
<label class="font-semibold w-30 flex-shrink-0">强度变化频率</label>
<div class="w-full flex-shrink flex gap-2 flex-col lg:items-center lg:flex-row lg:gap-8">
<div class="h-6 lg:h-auto flex-grow flex items-center">
<Slider class="w-full" v-model="randomFreq" range :max="60" />
Expand All @@ -377,6 +380,22 @@ watch(gameConfig, () => {
</div>
</div>
</div>
<div class="w-full flex flex-col md:flex-row items-top lg:items-center gap-2 lg:gap-8 mb-8 lg:mb-4">
<label class="font-semibold w-30">基础强度</label>
<InputNumber class="input-small" v-model="state.strengthVal" />
<div class="flex-grow flex-shrink"></div>
</div>
<div class="w-full flex flex-col md:flex-row items-top lg:items-center gap-2 lg:gap-8 mb-8 lg:mb-4">
<label class="font-semibold w-30">随机强度</label>
<InputNumber class="input-small" v-model="state.randomStrengthVal" />
<div class="flex-grow flex-shrink"></div>
</div>
<div class="flex gap-8 mb-4 w-full">
<div class="w-30"></div>
<div class="opacity-60 text-right">
强度范围:{{ state.strengthVal }} - {{ state.strengthVal + state.randomStrengthVal }},强度上限请在DG-Lab中设置
</div>
</div>
<div class="flex items-center gap-2 lg:gap-8 mb-4 w-full">
<label class="font-semibold w-30">B通道</label>
<ToggleButton v-model="state.bChannelEnabled" onIcon="pi pi-circle-on" onLabel="已启用"
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/pages/Viewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ const initWebSocket = async () => {
});
wsClient.on('configUpdated', (config) => {
state.valLow = config.strength.minStrength;
state.valHigh = config.strength.maxStrength;
state.valLow = config.strength.strength;
state.valHigh = config.strength.randomStrength;
state.valLow = Math.min(state.valLow, state.valLimit);
state.valHigh = Math.min(state.valLow + state.valHigh, state.valLimit);
});
wsClient.on('gameStarted', () => {
Expand Down
2 changes: 1 addition & 1 deletion server/cli/build-schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ async function md5File(file) {
const typesList = [
{
file: './src/types/game.ts',
types: ['RandomStrengthConfig', 'CoyoteLiveGameConfig']
types: ['GameStrengthConfig', 'CoyoteLiveGameConfig']
},
{
file: './src/types/config.ts',
Expand Down
65 changes: 31 additions & 34 deletions server/src/controllers/game/CoyoteLiveGame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Task } from '../../utils/task';
import { asleep, randomInt, simpleObjEqual } from '../../utils/utils';
import { EventStore } from '../../utils/EventStore';
import { CoyoteLiveGameManager } from '../../managers/CoyoteLiveGameManager';
import { CoyoteLiveGameConfig, RandomStrengthConfig } from '../../types/game';
import { CoyoteLiveGameConfig, GameStrengthConfig } from '../../types/game';

export interface CoyoteLiveGameEventsListener {
(name: 'close', listener: () => void): void;
Expand All @@ -20,9 +20,9 @@ export interface CoyoteLiveGameEventsListener {
export class CoyoteLiveGame {
public client: DGLabWSClient;

public randomStrengthConfig: RandomStrengthConfig = {
minStrength: 0,
maxStrength: 0,
public strengthConfig: GameStrengthConfig = {
strength: 0,
randomStrength: 0,
minInterval: 10,
maxInterval: 20,
bChannelMultiplier: 0,
Expand All @@ -37,7 +37,7 @@ export class CoyoteLiveGame {

public get gameConfig(): CoyoteLiveGameConfig {
return {
strength: this.randomStrengthConfig,
strength: this.strengthConfig,
pulseId: this.currentPulse.id,
};
}
Expand All @@ -61,9 +61,9 @@ export class CoyoteLiveGame {
const configCache = CoyoteLiveGameManager.instance.configCache;
let hasCachedConfig = false;

let cachedRandomStrengthConfig = configCache.get(`${configCachePrefix}:strength`);
if (cachedRandomStrengthConfig) {
this.randomStrengthConfig = cachedRandomStrengthConfig;
let cachedGameStrengthConfig = configCache.get(`${configCachePrefix}:strength`);
if (cachedGameStrengthConfig) {
this.strengthConfig = cachedGameStrengthConfig;
hasCachedConfig = true;
}

Expand Down Expand Up @@ -95,16 +95,8 @@ export class CoyoteLiveGame {
this.stopGame().catch((error) => {
console.error('Failed to stop CoyoteLiveGame:', error);
});
} else if (strength.strength < this.randomStrengthConfig.minStrength) { // 强度低于随机强度时降低随机强度
const newMinStrength = strength.strength;
const deltaStrength = this.randomStrengthConfig.minStrength - newMinStrength;
this.randomStrengthConfig.minStrength = newMinStrength;
this.randomStrengthConfig.maxStrength -= deltaStrength;
configUpdated = true;
}

if (strength.limit < this.randomStrengthConfig.maxStrength) { // 强度上限小于随机强度上限时降低随机强度上限
this.randomStrengthConfig.maxStrength = strength.limit;
} else if (strength.strength < this.strengthConfig.strength) { // 强度低于随机强度时降低随机强度
this.strengthConfig.strength = strength.strength;
configUpdated = true;
}

Expand All @@ -131,13 +123,13 @@ export class CoyoteLiveGame {
public updateConfig(config: CoyoteLiveGameConfig): void {
let configUpdated = false;

if (!simpleObjEqual(config.strength, this.randomStrengthConfig)) {
this.randomStrengthConfig = config.strength;
if (!simpleObjEqual(config.strength, this.strengthConfig)) {
this.strengthConfig = config.strength;
configUpdated = true;

// 如果游戏未开始,且强度小于最低强度,需要更新强度,否则本地强度会被服务端强制更新
if (this.client.strength.strength < this.randomStrengthConfig.minStrength && this.gameTask) {
this.client.setStrength(Channel.A, this.randomStrengthConfig.minStrength).catch((error) => {
if (this.client.strength.strength < this.strengthConfig.strength && this.gameTask) {
this.client.setStrength(Channel.A, this.strengthConfig.strength).catch((error) => {
console.error('Failed to set strength:', error);
});
}
Expand Down Expand Up @@ -165,7 +157,7 @@ export class CoyoteLiveGame {
}

private async runGameTask(ab: AbortController, harvest: () => void): Promise<void> {
let nextRandomStrengthTime = randomInt(this.randomStrengthConfig.minInterval, this.randomStrengthConfig.maxInterval) * 1000;
let nextRandomStrengthTime = randomInt(this.strengthConfig.minInterval, this.strengthConfig.maxInterval) * 1000;


// 输出脉冲,直到下次随机强度时间
Expand All @@ -174,7 +166,7 @@ export class CoyoteLiveGame {
let [pulseData, pulseDuration] = DGLabPulseService.instance.buildPulse(this.currentPulse);

await this.client.sendPulse(Channel.A, pulseData);
if (this.randomStrengthConfig && this.randomStrengthConfig.bChannelMultiplier) {
if (this.strengthConfig && this.strengthConfig.bChannelMultiplier) {
await this.client.sendPulse(Channel.B, pulseData);
}

Expand All @@ -193,17 +185,22 @@ export class CoyoteLiveGame {

// 随机强度前先清空当前队列,避免强度突变
await this.client.clearPulse(Channel.A);
if (this.randomStrengthConfig.bChannelMultiplier) {
if (this.strengthConfig.bChannelMultiplier) {
await this.client.clearPulse(Channel.B);
}

harvest();

// 随机强度
let strength = randomInt(this.randomStrengthConfig.minStrength, this.randomStrengthConfig.maxStrength);
let strength = this.strengthConfig.strength;
if (this.strengthConfig.randomStrength) {
// 随机强度
strength += randomInt(0, this.strengthConfig.randomStrength);
strength = Math.min(strength, this.clientStrength.limit);
}

await this.client.setStrength(Channel.A, strength);
if (this.randomStrengthConfig.bChannelMultiplier) {
await this.client.setStrength(Channel.B, strength * this.randomStrengthConfig.bChannelMultiplier);
if (this.strengthConfig.bChannelMultiplier) {
await this.client.setStrength(Channel.B, strength * this.strengthConfig.bChannelMultiplier);
}
}

Expand All @@ -214,10 +211,10 @@ export class CoyoteLiveGame {
public async startGame(ignoreEvent = false): Promise<void> {
if (!this.gameTask) {
// 初始化强度和脉冲
const minStrength = this.randomStrengthConfig.minStrength;
await this.client.setStrength(Channel.A, minStrength);
if (this.randomStrengthConfig.bChannelMultiplier) {
await this.client.setStrength(Channel.B, minStrength * this.randomStrengthConfig.bChannelMultiplier);
const initStrength = this.strengthConfig.strength;
await this.client.setStrength(Channel.A, initStrength);
if (this.strengthConfig.bChannelMultiplier) {
await this.client.setStrength(Channel.B, initStrength * this.strengthConfig.bChannelMultiplier);
} else {
await this.client.setStrength(Channel.B, 0);
}
Expand Down Expand Up @@ -276,7 +273,7 @@ export class CoyoteLiveGame {
// 保存配置, 以便下次连接时恢复
const configCachePrefix = `coyoteLiveGameConfig:${this.client.clientId}:`;
const configCache = CoyoteLiveGameManager.instance.configCache;
configCache.set(`${configCachePrefix}:strength`, this.randomStrengthConfig);
configCache.set(`${configCachePrefix}:strength`, this.strengthConfig);
configCache.set(`${configCachePrefix}:pulseId`, this.currentPulse.id);

this.events.emit('close');
Expand Down
Loading

0 comments on commit 96861d9

Please sign in to comment.