Skip to content

Commit

Permalink
Mod detection & new among us ver
Browse files Browse the repository at this point in the history
  • Loading branch information
OhMyGuus committed May 10, 2021
1 parent 9b73da5 commit 741a870
Show file tree
Hide file tree
Showing 13 changed files with 197 additions and 160 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bettercrewlink",
"version": "2.6.1",
"version": "2.6.3",
"license": "GPL-3.0-or-later",
"description": "Free, open, Among Us proximity voice chat",
"repository": {
Expand Down
2 changes: 2 additions & 0 deletions src/common/AmongUsState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface AmongUsState {
closedDoors: number[];
currentServer: string;
maxPlayers: number;
mod: string;
}

export interface Player {
Expand Down Expand Up @@ -80,4 +81,5 @@ export interface VoiceState {
localIsAlive: boolean;
muted: boolean;
deafened: boolean;
mod: string;
}
1 change: 1 addition & 0 deletions src/common/ObsOverlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ export interface ObsVoiceState {
otherDead: ClientBoolMap;
localTalking: boolean;
localIsAlive: boolean;
mod: string;
}
6 changes: 6 additions & 0 deletions src/common/PublicLobby.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export interface AmongusMod {
id: string;
label: string;
dllStartsWith?: string
}


Expand All @@ -13,18 +14,23 @@ export const modList: AmongusMod[] = [
{
id: 'TOWN_OF_US',
label: 'Town of Us',
dllStartsWith: 'TownOfUs'
},
{
id: 'TOWN_OF_IMPOSTORS',
label: 'Town of Impostors',
dllStartsWith: 'TownOfImpostors'

},
{
id: 'THE_OTHER_ROLES',
label: 'The Other Roles',
dllStartsWith: 'TheOtherRoles'
},
{
id: 'EXTRA_ROLES',
label: 'Extra Roles',
dllStartsWith: 'ExtraRoles'
},
{
id: 'OTHER',
Expand Down
52 changes: 39 additions & 13 deletions src/main/GameReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
virtualAllocEx,
writeBuffer,
writeMemory,
getProcessPath,
} from 'memoryjs';
import Struct from 'structron';
import { IpcOverlayMessages, IpcRendererMessages } from '../common/ipc-messages';
Expand All @@ -22,6 +23,9 @@ import { GenerateAvatars, numberToColorHex } from './avatarGenerator';
import { RainbowColorId } from '../renderer/cosmetics';
import { TempFixOffsets, TempFixOffsets2 } from './offsetStore';
import { platform } from 'os';
import fs from 'fs';
import path from 'path';
import { AmongusMod, modList } from '../common/PublicLobby';

interface ValueType<T> {
read(buffer: BufferSource, offset: number): T;
Expand Down Expand Up @@ -52,6 +56,7 @@ export default class GameReader {
lastPlayerPtr = 0;
shouldReadLobby = false;
is_64bit = false;
is_linux = false;
oldGameState = GameState.UNKNOWN;
lastState: AmongUsState = {} as AmongUsState;
amongUs: ProcessObject | null = null;
Expand All @@ -63,6 +68,14 @@ export default class GameReader {
currentServer = '';
disableWriting = false;
pid = -1;
loadedMod = modList[0];
gamePath = '';

constructor(sendIPC: Electron.WebContents['send']) {
this.is_linux = platform() === 'linux';
this.sendIPC = sendIPC;
}

checkProcessOpen(): void {
const processesOpen = getProcesses().filter((p) => p.szExeFile === 'Among Us.exe');
let error = '';
Expand All @@ -73,6 +86,8 @@ export default class GameReader {
this.pid = processOpen.th32ProcessID;
this.amongUs = openProcess(processOpen.th32ProcessID);
this.gameAssembly = findModule('GameAssembly.dll', this.amongUs.th32ProcessID);
this.gamePath = getProcessPath(this.amongUs.handle);
this.loadedMod = this.getInstalledMods(this.gamePath);
this.initializeoffsets();
this.sendIPC(IpcRendererMessages.NOTIFY_GAME_OPENED, true);
break;
Expand All @@ -97,6 +112,25 @@ export default class GameReader {
}
return;
}

getInstalledMods(filePath: string): AmongusMod {
const pathLower = filePath.toLowerCase();
if (pathLower.includes('epic') || pathLower.includes('?\\volume') || this.is_linux) {
return modList[0];
} else {
let dir = path.dirname(filePath);
let loadedWinHttp = fs.existsSync(path.join(dir, 'winhttp.dll'));
if (!loadedWinHttp) {
return modList[0];
}
for (const file of fs.readdirSync(path.join(dir, 'BepInEx\\plugins'))) {
let mod = modList.find((o) => o.dllStartsWith && file.includes(o.dllStartsWith));
if (mod) return mod;
}
return modList[0];
}
}

checkProcessDelay = 0;
loop(): string | null {
if (this.checkProcessDelay-- <= 0) {
Expand Down Expand Up @@ -337,6 +371,7 @@ export default class GameReader {
lightRadius,
lightRadiusChanged: lightRadius != this.lastState?.lightRadius,
map,
mod: this.loadedMod.id,
closedDoors,
currentServer: this.currentServer,
maxPlayers,
Expand All @@ -355,10 +390,6 @@ export default class GameReader {
return null;
}

constructor(sendIPC: Electron.WebContents['send']) {
this.sendIPC = sendIPC;
}

initializeoffsets(): void {
console.log('INITIALIZEOFFSETS???');
this.is_64bit = this.isX64Version();
Expand Down Expand Up @@ -457,14 +488,7 @@ export default class GameReader {
}

initializeWrites(): void {
if (
this.isX64Version() ||
!this.offsets ||
!this.amongUs ||
!this.gameAssembly ||
this.disableWriting ||
platform() === 'linux'
) {
if (this.is_64bit || !this.offsets || !this.amongUs || !this.gameAssembly || this.disableWriting || this.is_linux) {
//not supported atm
return;
}
Expand Down Expand Up @@ -858,7 +882,9 @@ export default class GameReader {
let x = this.readMemory<number>('float', data.objectPtr, positionOffsets[0]);
let y = this.readMemory<number>('float', data.objectPtr, positionOffsets[1]);
const isDummy = this.readMemory<boolean>('boolean', data.objectPtr, this.offsets.player.isDummy);

if (isDummy) {
console.log('ISDUMMY!!!!@!@!');
}
let bugged = false;
if (x === undefined || y === undefined || data.disconnected != 0 || data.color > 40) {
x = 9999;
Expand Down
1 change: 0 additions & 1 deletion src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,6 @@ if (!gotTheLock) {
});

ipcMain.on('update-app', () => {
app.relaunch();
autoUpdater.quitAndInstall();
});

Expand Down
3 changes: 3 additions & 0 deletions src/main/memoryjs.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ declare module 'memoryjs' {

export function readBuffer(handle: number, address: number, size: number, callback?: Callback<Buffer>): Buffer;

export function getProcessPath(handle: number): string;


export function writeMemory<T>(handle: number, address: number, value: T, dataType: DataType): void;

export function writeBuffer(handle: number, address: number, buffer: Buffer): void;
Expand Down
5 changes: 2 additions & 3 deletions src/main/offsetStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,7 @@ export default {
addressOffset: 0,
},
gameData: {
sig:
'8B 0D ? ? ? ? 8B F0 83 C4 10 8B 49 5C 8B 01 85 C0 0F 84 ? ? ? ? 6A 00 FF 75 F4 50 E8 ? ? ? ? 83 C4 0C 89 45 E8 85 C0',
sig: '8B 0D ? ? ? ? 8B F0 83 C4 10 8B 49 5C 8B 01',
patternOffset: 2,
addressOffset: 0,
},
Expand All @@ -332,7 +331,7 @@ export default {
addressOffset: 0,
},
playerControl: {
sig: '8B 0D ? ? ? ? 83 C4 04 8B 41 5C 8B 00 85 C0 74 2B C6 40 30 00',
sig: '8B 0D ? ? ? ? 83 C4 04 8B 41 5C 8B 00 85 C0 74 2B',
patternOffset: 2,
addressOffset: 0,
},
Expand Down
36 changes: 22 additions & 14 deletions src/renderer/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useRef } from 'react';
import { Player } from '../common/AmongUsState';
import { backLayerHats, hatOffsets, getCosmetic, redAlive, cosmeticType } from './cosmetics';
import { backLayerHats, getCosmetic, redAlive, cosmeticType, getHatDementions, HatDementions } from './cosmetics';
import makeStyles from '@material-ui/core/styles/makeStyles';
import MicOff from '@material-ui/icons/MicOff';
import VolumeOff from '@material-ui/icons/VolumeOff';
Expand Down Expand Up @@ -64,6 +64,7 @@ export interface CanvasProps {
overflow: boolean;
usingRadio: boolean | undefined;
onClick?: () => void;
mod: string;
}

export interface AvatarProps {
Expand All @@ -82,6 +83,7 @@ export interface AvatarProps {
overflow?: boolean;
isUsingRadio?: boolean;
onConfigChange?: () => void;
mod: string;
}

const Avatar: React.FC<AvatarProps> = function ({
Expand All @@ -100,6 +102,7 @@ const Avatar: React.FC<AvatarProps> = function ({
lookLeft = false,
overflow = false,
onConfigChange,
mod,
}: AvatarProps) {
const classes = useStyles();
let icon;
Expand Down Expand Up @@ -134,6 +137,7 @@ const Avatar: React.FC<AvatarProps> = function ({
size={size}
overflow={overflow}
usingRadio={isUsingRadio}
mod={mod}
/>
);

Expand Down Expand Up @@ -202,7 +206,7 @@ const Avatar: React.FC<AvatarProps> = function ({
interface UseCanvasStylesParams {
backLayerHat: boolean;
isAlive: boolean;
hatY: string;
hatDementions: HatDementions;
lookLeft: boolean;
size: number;
borderColor: string;
Expand All @@ -217,10 +221,11 @@ const useCanvasStyles = makeStyles(() => ({
zIndex: 2,
},
hat: {
width: '105%',
width: ({ hatDementions }: UseCanvasStylesParams) => hatDementions.width,
position: 'absolute',
top: ({ hatY }: UseCanvasStylesParams) => `calc(22% + ${hatY})`,
left: ({ size, paddingLeft }: UseCanvasStylesParams) => Math.max(2, size / 40) / 2 + paddingLeft,
top: ({ hatDementions }: UseCanvasStylesParams) => `calc(22% + ${hatDementions.top})`,
left: ({ size, paddingLeft, hatDementions }: UseCanvasStylesParams) =>
`calc(${hatDementions.left} + ${Math.max(2, size / 40) / 2 + paddingLeft}px)`, //`calc(${hatDementions.left} + ${Math.max(2, size / 40) / 2 + paddingLeft})` ,
zIndex: ({ backLayerHat }: UseCanvasStylesParams) => (backLayerHat ? 1 : 4),
display: ({ isAlive }: UseCanvasStylesParams) => (isAlive ? 'block' : 'none'),
},
Expand Down Expand Up @@ -268,25 +273,27 @@ function Canvas({
overflow,
usingRadio,
onClick,
mod,
}: CanvasProps) {
const hatImg = useRef<HTMLImageElement>(null);
const skinImg = useRef<HTMLImageElement>(null);
const image = useRef<HTMLImageElement>(null);
const hatY = hatOffsets[hat] || '-33%';
const hatDementions = getHatDementions(hat, 'TOWN_OF_US');
const classes = useCanvasStyles({
backLayerHat: backLayerHats.has(hat),
isAlive,
hatY,
hatDementions: hatDementions,
lookLeft,
size,
borderColor,
paddingLeft: -7,
});

//@ts-ignore
//@ts-ignore
const onerror = (e: any) => {
e.target.onError = null;
e.target.src = '';
console.log("ONERROR: ", e.target.src)
e.target.src = undefined;
e.target.style.display='none'
};
return (
<>
Expand All @@ -313,7 +320,7 @@ function Canvas({
/>

<img
src={getCosmetic(color, isAlive, cosmeticType.skin, skin)}
src={getCosmetic(color, isAlive, cosmeticType.skin, skin, mod)}
style={{ top: skin === 17 ? '0%' : undefined }}
ref={skinImg}
className={classes.skin}
Expand All @@ -322,16 +329,17 @@ function Canvas({

{overflow && (
<img
src={getCosmetic(color, isAlive, cosmeticType.hat, hat)}
src={getCosmetic(color, isAlive, cosmeticType.hat, hat, mod)}
ref={hatImg}
className={classes.hat}
onError={onerror}
onLoad={onerror}

/>
)}
</div>
{!overflow && (
<img
src={getCosmetic(color, isAlive, cosmeticType.hat, hat)}
src={getCosmetic(color, isAlive, cosmeticType.hat, hat, mod)}
ref={hatImg}
className={classes.hat}
onError={onerror}
Expand Down
1 change: 1 addition & 0 deletions src/renderer/Overlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ const AvatarOverlay: React.FC<AvatarOverlayProps> = ({
lookLeft={!(positionParse === 'left' || positionParse === 'bottom_left')}
overflow={isOnSide && !showName}
showHat={true}
mod={voiceState.mod}
/>
</div>
{showName && (
Expand Down
8 changes: 7 additions & 1 deletion src/renderer/Voice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,7 @@ const Voice: React.FC<VoiceProps> = function ({ t, error: initialError }: VoiceP
otherDead,
localTalking: talking,
localIsAlive: !myPlayer?.isDead,
mod: gameState.mod,
};
connectionStuff.current.overlaySocket?.emit('signal', {
to: settings.obsSecret,
Expand Down Expand Up @@ -648,8 +649,10 @@ const Voice: React.FC<VoiceProps> = function ({ t, error: initialError }: VoiceP
max_players: gameState.maxPlayers,
server: gameState.currentServer,
language: lobbySettings.publicLobby_language,
mods: lobbySettings.publicLobby_mods,
mods: gameState.mod !== 'NONE' ? gameState.mod : lobbySettings.publicLobby_mods,
isPublic: lobbySettings.publicLobby_on && gameState.gameState == GameState.LOBBY,
isPublic2:lobbySettings.publicLobby_on, // TEMP DEBUG
gameState: gameState.gameState,
});
};

Expand Down Expand Up @@ -1284,6 +1287,7 @@ const Voice: React.FC<VoiceProps> = function ({ t, error: initialError }: VoiceP
impostorRadioClientId: !myPlayer?.isImpostor ? -1 : impostorRadioClientId.current,
muted: mutedState,
deafened: deafenedState,
mod: gameState.mod,
} as VoiceState);
}, [
otherTalking,
Expand Down Expand Up @@ -1323,6 +1327,7 @@ const Voice: React.FC<VoiceProps> = function ({ t, error: initialError }: VoiceP
talking={talking}
isAlive={!myPlayer.isDead}
size={100}
mod={gameState.mod}
/>
</div>
</>
Expand Down Expand Up @@ -1417,6 +1422,7 @@ const Voice: React.FC<VoiceProps> = function ({ t, error: initialError }: VoiceP
onConfigChange={() => {
store.set(`playerConfigMap.${player.nameHash}`, playerConfigs[player.nameHash]);
}}
mod={gameState.mod}
/>
</Grid>
);
Expand Down
Loading

0 comments on commit 741a870

Please sign in to comment.