From e5bc281ef6a1b9f4a495c5c44e5ee747d85e352c Mon Sep 17 00:00:00 2001 From: Mikhail Babynichev Date: Mon, 4 Mar 2024 20:29:32 +0300 Subject: [PATCH] fix: memory leak on bindings states --- .../tosu/src/entities/AllTimesData/index.ts | 100 ++++++++++-------- packages/tsprocess/src/process.ts | 14 ++- 2 files changed, 62 insertions(+), 52 deletions(-) diff --git a/packages/tosu/src/entities/AllTimesData/index.ts b/packages/tosu/src/entities/AllTimesData/index.ts index 9ef5cc20..6032c016 100644 --- a/packages/tosu/src/entities/AllTimesData/index.ts +++ b/packages/tosu/src/entities/AllTimesData/index.ts @@ -26,6 +26,8 @@ export class AllTimesData extends AbstractEntity { ShowInterface: boolean = false; IsWatchingReplay: number = 0; + bindingNames = new Map(); + private configList: Record = { VolumeUniversal: { type: 'int', @@ -320,77 +322,87 @@ export class AllTimesData extends AbstractEntity { super(services); } - async updateConfigState( + updateConfigState( process: Process, settings: Settings, configurationAddr: number ) { try { - process.readSharpDictionary(configurationAddr, (current) => { - const key = process.readSharpString(process.readInt(current)); + const rawSharpDictionary = + process.readSharpDictionary(configurationAddr); + for (let i = 0; i < rawSharpDictionary.length; i++) { + const current = rawSharpDictionary[i]; + const keyAddress = process.readInt(current); + let key; + if (this.bindingNames.has(keyAddress)) { + key = this.bindingNames.get(keyAddress); + } else { + key = process.readSharpString(keyAddress); + this.bindingNames.set(keyAddress, key); + } const bindable = process.readInt(current + 0x4); - const configBindable = this.configList[key]; - - if (configBindable !== undefined) { - let value: any; + if (!(key in this.configList)) { + continue; + } + let value: any; - switch (configBindable.type) { - case 'byte': - value = process.readByte(bindable + 0xc); - break; - case 'bool': - value = process.readByte(bindable + 0xc) == 1; - break; - case 'int': - case 'double': - value = process.readDouble(bindable + 0x4); - break; - case 'string': - value = process.readSharpString( - process.readInt(current + 0x4) - ); - break; - case 'bstring': - value = process.readSharpString( - process.readInt(bindable + 0x4) - ); - break; - case 'enum': - value = process.readInt(bindable + 0xc); - break; - default: - return false; - } + switch (this.configList[key].type) { + case 'byte': + value = process.readByte(bindable + 0xc); + break; + case 'bool': + value = Boolean(process.readByte(bindable + 0xc)); + break; + case 'int': + case 'double': + value = process.readDouble(bindable + 0x4); + break; + case 'string': + value = process.readSharpString( + process.readInt(current + 0x4) + ); + break; + case 'bstring': + value = process.readSharpString( + process.readInt(bindable + 0x4) + ); + break; + case 'enum': + value = process.readInt(bindable + 0xc); + break; + default: + break; + } - configBindable.setValue(settings, value); + if (value) { + this.configList[key].setValue(settings, value); } - return true; - }); + } } catch (exc) { wLogger.error("can't update config state"); console.error(exc); } } - async updateBindingState( + updateBindingState( process: Process, settings: Settings, bindingConfigAddr: number ) { try { - process.readSharpDictionary(bindingConfigAddr, (current) => { + const rawSharpDictionary = + process.readSharpDictionary(bindingConfigAddr); + for (let i = 0; i < rawSharpDictionary.length; i++) { + const current = rawSharpDictionary[i]; const key = process.readInt(current); const value = process.readInt(current + 0xc); const bindable = this.bindingList[key]; - - if (bindable !== undefined) { + if (bindable) { bindable.setValue(settings, value); } - - return true; - }); + } } catch (exc) { wLogger.error("can't update binding state"); console.error(exc); diff --git a/packages/tsprocess/src/process.ts b/packages/tsprocess/src/process.ts index 7458ec34..33a66aeb 100644 --- a/packages/tsprocess/src/process.ts +++ b/packages/tsprocess/src/process.ts @@ -77,20 +77,18 @@ export class Process { return endString; } - readSharpDictionary( - address: number, - onLoop: (current: number) => boolean - ): void { + readSharpDictionary(address: number): number[] { + const result = []; const items = this.readInt(address + 0x8); const size = this.readInt(address + 0x1c); for (let i = 0; i < size; i++) { - const current = items + 0x8 + 0x10 * i; + const address = items + 0x8 + 0x10 * i; - if (!onLoop(current)) { - return; - } + result.push(address); } + + return result; } readBuffer(address: number, size: number): Buffer {