Skip to content

Commit

Permalink
feat: chat reading (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
KotRikD authored Dec 20, 2023
1 parent e547bce commit 0091171
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 5 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Features Done
- [X] Menu state (map information, star rating, map metadata)
- [X] Gameplay information (300's, 100's, 50's, live pp calculations, other stuff)
- [X] ResultScreen information (result screen information with grades + gameplay data)
- [ ] Tournament state (in beta right now, dont have chat reading, and some output data)
- [x] Tournament state
- [x] In-game overlay (based on gosumemory closed overlay injection)

### 🏠 [Homepage](https://github.com/KotRikD/tosu#readme)
Expand Down Expand Up @@ -74,7 +74,7 @@ pnpm install
#### Compile TS & App

```sh
pnpm run compile
pnpm run build
```

## Usage
Expand Down
1 change: 0 additions & 1 deletion packages/tosu/src/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,6 @@ interface TourneyGameplay {

export interface TourneyIpcClient {
team: string;
ipcSpec: string;
spectating: TourneyIpcSpec;
gameplay: TourneyGameplay;
}
Expand Down
21 changes: 19 additions & 2 deletions packages/tosu/src/api/utils/buildResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import path from 'path';
import { DataRepo } from '@/entities/DataRepoList';
import { LeaderboardPlayer as MemoryLeaderboardPlayer } from '@/entities/GamePlayData/Leaderboard';
import { InstanceManager } from '@/objects/instanceManager/instanceManager';
import { OsuInstance } from '@/objects/instanceManager/osuInstance';
import { getOsuModsString } from '@/utils/osuMods';

import {
Expand Down Expand Up @@ -273,7 +274,6 @@ const buildTourneyData = (

return {
team: spectatorTeam,
ipcSpec: '',
spectating: {
name: tourneyUserProfileData.Name,
country: tourneyUserProfileData.Country,
Expand Down Expand Up @@ -325,6 +325,23 @@ const buildTourneyData = (
'tourneyManagerData'
]);

const mappedChat = tourneyManagerData.Messages.map((message) => {
const ipcClient = mappedOsuTourneyClients.find(
(client) => client.spectating.name === message.name
);

return {
team: ipcClient
? ipcClient.team
: message.name === 'BanchoBot'
? 'bot'
: 'unknown',
time: message.time,
name: message.name,
messageBody: message.content
};
});

return {
manager: {
ipcState: tourneyManagerData.IPCState,
Expand All @@ -341,7 +358,7 @@ const buildTourneyData = (
scoreVisible: tourneyManagerData.ScoreVisible,
starsVisible: tourneyManagerData.StarsVisible
},
chat: [],
chat: mappedChat,
gameplay: {
score: {
left: tourneyManagerData.FirstTeamScore,
Expand Down
81 changes: 81 additions & 0 deletions packages/tosu/src/entities/TourneyManagerData/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ import { DataRepo } from '@/entities/DataRepoList';
import { wLogger } from '@/logger';

import { AbstractEntity } from '../AbstractEntity';
import { ITourneyManagetChatItem } from './types';

const TOURNAMENT_CHAT_AREA = '33 47 9D FF 5B 7F FF FF';

export class TourneyManagerData extends AbstractEntity {
ChatAreaAddr: number = 0;

IPCState: number = 0;
LeftStars: number = 0;
RightStars: number = 0;
Expand All @@ -16,6 +21,8 @@ export class TourneyManagerData extends AbstractEntity {
SecondTeamScore: number = 0;
IPCBaseAddr: number = 0;

Messages: ITourneyManagetChatItem[] = [];

constructor(services: DataRepo) {
super(services);
}
Expand Down Expand Up @@ -48,6 +55,12 @@ export class TourneyManagerData extends AbstractEntity {
return;
}

if (this.ChatAreaAddr === 0) {
this.ChatAreaAddr = process.scanSync(TOURNAMENT_CHAT_AREA, true);
wLogger.debug('[TMD] Chat area found');
return;
}

const teamLeftBase = process.readInt(rulesetAddr + 0x1c);
const teamRightBase = process.readInt(rulesetAddr + 0x20);

Expand Down Expand Up @@ -84,6 +97,74 @@ export class TourneyManagerData extends AbstractEntity {
process.readInt(process.readInt(rulesetAddr + 0x34) + 0x4) + 0x4
);

const chatBase = this.ChatAreaAddr - 0x44;

// [Base + 0x1C] + 0x4
const tabsBase = process.readInt(
process.readInt(chatBase + 0x1c) + 0x4
);
const tabsLength = process.readInt(tabsBase + 0x4);

for (let i = 0; i < tabsLength; i++) {
const current = tabsBase + bases.leaderStart + 0x4 * i;

const slotAddr = process.readInt(current);
if (slotAddr === 0) {
continue;
}

// [[Base + 0xC] + 0x4]
const chatTag = process.readSharpString(
process.readInt(process.readInt(slotAddr + 0xc) + 0x4)
);
if (chatTag !== '#multiplayer') {
continue;
}

const result: ITourneyManagetChatItem[] = [];

// [[Base + 0xC] + 0x10] + 0x4
const messagesAddr = process.readInt(
process.readInt(slotAddr + 0xc) + 0x10
);

const messagesItems = process.readInt(messagesAddr + 0x4);
const messagesSize = process.readInt(messagesAddr + 0xc);

if (this.Messages.length === messagesSize) {
// Not needed an update
continue;
}

for (let i = 0; i < messagesSize; i++) {
let current = messagesItems + bases.leaderStart + 0x4 * i;
let currentItem = process.readInt(current);

// [Base + 0x4]
let content = process.readSharpString(
process.readInt(currentItem + 0x4)
);
// NOTE: Check for empty, and !mp commands
if (content === '' || content.startsWith('!mp')) {
continue;
}
// [Base + 0x8]
let timeName = process.readSharpString(
process.readInt(currentItem + 0x8)
);
let [time, name] = timeName.split(' ');

result.push({
time: time.trim(),
name: name.substring(0, name.length - 1),
content
});
}

this.Messages = result;
wLogger.debug('[TourneyManagerData:chat] updated');
}

wLogger.debug(`[TourneyManagerData:updateState] updated`);
}
}
5 changes: 5 additions & 0 deletions packages/tosu/src/entities/TourneyManagerData/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type ITourneyManagetChatItem = {
time: string;
name: string;
content: string;
};

0 comments on commit 0091171

Please sign in to comment.